| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409 |
- /**
- * @license
- * Copyright Google LLC All Rights Reserved.
- *
- * Use of this source code is governed by an MIT-style license that can be
- * found in the LICENSE file at https://angular.io/license
- */
- import { InjectionToken, Directive, forwardRef, Input, Injectable, NgZone, Optional, SkipSelf, ElementRef, NgModule, IterableDiffers, TemplateRef, ViewContainerRef, ChangeDetectionStrategy, ChangeDetectorRef, Component, Inject, Output, ViewChild, ViewEncapsulation, ɵɵdefineInjectable, ɵɵinject } from '@angular/core';
- import { coerceNumberProperty } from '@angular/cdk/coercion';
- import { Subject, fromEvent, of, Observable, animationFrameScheduler, asapScheduler, merge } from 'rxjs';
- import { distinctUntilChanged, auditTime, filter, takeUntil, startWith, pairwise, shareReplay, switchMap } from 'rxjs/operators';
- import { Platform, getRtlScrollAxisType, RtlScrollAxisType, supportsScrollBehavior, PlatformModule } from '@angular/cdk/platform';
- import { Directionality, BidiModule } from '@angular/cdk/bidi';
- import { __extends } from 'tslib';
- import { ArrayDataSource, isDataSource } from '@angular/cdk/collections';
- /**
- * @fileoverview added by tsickle
- * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
- */
- /**
- * The injection token used to specify the virtual scrolling strategy.
- * @type {?}
- */
- var VIRTUAL_SCROLL_STRATEGY = new InjectionToken('VIRTUAL_SCROLL_STRATEGY');
- /**
- * @fileoverview added by tsickle
- * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
- */
- /**
- * Virtual scrolling strategy for lists with items of known fixed size.
- */
- var /**
- * Virtual scrolling strategy for lists with items of known fixed size.
- */
- FixedSizeVirtualScrollStrategy = /** @class */ (function () {
- /**
- * @param itemSize The size of the items in the virtually scrolling list.
- * @param minBufferPx The minimum amount of buffer (in pixels) before needing to render more
- * @param maxBufferPx The amount of buffer (in pixels) to render when rendering more.
- */
- function FixedSizeVirtualScrollStrategy(itemSize, minBufferPx, maxBufferPx) {
- this._scrolledIndexChange = new Subject();
- /**
- * \@docs-private Implemented as part of VirtualScrollStrategy.
- */
- this.scrolledIndexChange = this._scrolledIndexChange.pipe(distinctUntilChanged());
- /**
- * The attached viewport.
- */
- this._viewport = null;
- this._itemSize = itemSize;
- this._minBufferPx = minBufferPx;
- this._maxBufferPx = maxBufferPx;
- }
- /**
- * Attaches this scroll strategy to a viewport.
- * @param viewport The viewport to attach this strategy to.
- */
- /**
- * Attaches this scroll strategy to a viewport.
- * @param {?} viewport The viewport to attach this strategy to.
- * @return {?}
- */
- FixedSizeVirtualScrollStrategy.prototype.attach = /**
- * Attaches this scroll strategy to a viewport.
- * @param {?} viewport The viewport to attach this strategy to.
- * @return {?}
- */
- function (viewport) {
- this._viewport = viewport;
- this._updateTotalContentSize();
- this._updateRenderedRange();
- };
- /** Detaches this scroll strategy from the currently attached viewport. */
- /**
- * Detaches this scroll strategy from the currently attached viewport.
- * @return {?}
- */
- FixedSizeVirtualScrollStrategy.prototype.detach = /**
- * Detaches this scroll strategy from the currently attached viewport.
- * @return {?}
- */
- function () {
- this._scrolledIndexChange.complete();
- this._viewport = null;
- };
- /**
- * Update the item size and buffer size.
- * @param itemSize The size of the items in the virtually scrolling list.
- * @param minBufferPx The minimum amount of buffer (in pixels) before needing to render more
- * @param maxBufferPx The amount of buffer (in pixels) to render when rendering more.
- */
- /**
- * Update the item size and buffer size.
- * @param {?} itemSize The size of the items in the virtually scrolling list.
- * @param {?} minBufferPx The minimum amount of buffer (in pixels) before needing to render more
- * @param {?} maxBufferPx The amount of buffer (in pixels) to render when rendering more.
- * @return {?}
- */
- FixedSizeVirtualScrollStrategy.prototype.updateItemAndBufferSize = /**
- * Update the item size and buffer size.
- * @param {?} itemSize The size of the items in the virtually scrolling list.
- * @param {?} minBufferPx The minimum amount of buffer (in pixels) before needing to render more
- * @param {?} maxBufferPx The amount of buffer (in pixels) to render when rendering more.
- * @return {?}
- */
- function (itemSize, minBufferPx, maxBufferPx) {
- if (maxBufferPx < minBufferPx) {
- throw Error('CDK virtual scroll: maxBufferPx must be greater than or equal to minBufferPx');
- }
- this._itemSize = itemSize;
- this._minBufferPx = minBufferPx;
- this._maxBufferPx = maxBufferPx;
- this._updateTotalContentSize();
- this._updateRenderedRange();
- };
- /** @docs-private Implemented as part of VirtualScrollStrategy. */
- /**
- * \@docs-private Implemented as part of VirtualScrollStrategy.
- * @return {?}
- */
- FixedSizeVirtualScrollStrategy.prototype.onContentScrolled = /**
- * \@docs-private Implemented as part of VirtualScrollStrategy.
- * @return {?}
- */
- function () {
- this._updateRenderedRange();
- };
- /** @docs-private Implemented as part of VirtualScrollStrategy. */
- /**
- * \@docs-private Implemented as part of VirtualScrollStrategy.
- * @return {?}
- */
- FixedSizeVirtualScrollStrategy.prototype.onDataLengthChanged = /**
- * \@docs-private Implemented as part of VirtualScrollStrategy.
- * @return {?}
- */
- function () {
- this._updateTotalContentSize();
- this._updateRenderedRange();
- };
- /** @docs-private Implemented as part of VirtualScrollStrategy. */
- /**
- * \@docs-private Implemented as part of VirtualScrollStrategy.
- * @return {?}
- */
- FixedSizeVirtualScrollStrategy.prototype.onContentRendered = /**
- * \@docs-private Implemented as part of VirtualScrollStrategy.
- * @return {?}
- */
- function () { };
- /** @docs-private Implemented as part of VirtualScrollStrategy. */
- /**
- * \@docs-private Implemented as part of VirtualScrollStrategy.
- * @return {?}
- */
- FixedSizeVirtualScrollStrategy.prototype.onRenderedOffsetChanged = /**
- * \@docs-private Implemented as part of VirtualScrollStrategy.
- * @return {?}
- */
- function () { };
- /**
- * Scroll to the offset for the given index.
- * @param index The index of the element to scroll to.
- * @param behavior The ScrollBehavior to use when scrolling.
- */
- /**
- * Scroll to the offset for the given index.
- * @param {?} index The index of the element to scroll to.
- * @param {?} behavior The ScrollBehavior to use when scrolling.
- * @return {?}
- */
- FixedSizeVirtualScrollStrategy.prototype.scrollToIndex = /**
- * Scroll to the offset for the given index.
- * @param {?} index The index of the element to scroll to.
- * @param {?} behavior The ScrollBehavior to use when scrolling.
- * @return {?}
- */
- function (index, behavior) {
- if (this._viewport) {
- this._viewport.scrollToOffset(index * this._itemSize, behavior);
- }
- };
- /** Update the viewport's total content size. */
- /**
- * Update the viewport's total content size.
- * @private
- * @return {?}
- */
- FixedSizeVirtualScrollStrategy.prototype._updateTotalContentSize = /**
- * Update the viewport's total content size.
- * @private
- * @return {?}
- */
- function () {
- if (!this._viewport) {
- return;
- }
- this._viewport.setTotalContentSize(this._viewport.getDataLength() * this._itemSize);
- };
- /** Update the viewport's rendered range. */
- /**
- * Update the viewport's rendered range.
- * @private
- * @return {?}
- */
- FixedSizeVirtualScrollStrategy.prototype._updateRenderedRange = /**
- * Update the viewport's rendered range.
- * @private
- * @return {?}
- */
- function () {
- if (!this._viewport) {
- return;
- }
- /** @type {?} */
- var scrollOffset = this._viewport.measureScrollOffset();
- /** @type {?} */
- var firstVisibleIndex = scrollOffset / this._itemSize;
- /** @type {?} */
- var renderedRange = this._viewport.getRenderedRange();
- /** @type {?} */
- var newRange = { start: renderedRange.start, end: renderedRange.end };
- /** @type {?} */
- var viewportSize = this._viewport.getViewportSize();
- /** @type {?} */
- var dataLength = this._viewport.getDataLength();
- /** @type {?} */
- var startBuffer = scrollOffset - newRange.start * this._itemSize;
- if (startBuffer < this._minBufferPx && newRange.start != 0) {
- /** @type {?} */
- var expandStart = Math.ceil((this._maxBufferPx - startBuffer) / this._itemSize);
- newRange.start = Math.max(0, newRange.start - expandStart);
- newRange.end = Math.min(dataLength, Math.ceil(firstVisibleIndex + (viewportSize + this._minBufferPx) / this._itemSize));
- }
- else {
- /** @type {?} */
- var endBuffer = newRange.end * this._itemSize - (scrollOffset + viewportSize);
- if (endBuffer < this._minBufferPx && newRange.end != dataLength) {
- /** @type {?} */
- var expandEnd = Math.ceil((this._maxBufferPx - endBuffer) / this._itemSize);
- if (expandEnd > 0) {
- newRange.end = Math.min(dataLength, newRange.end + expandEnd);
- newRange.start = Math.max(0, Math.floor(firstVisibleIndex - this._minBufferPx / this._itemSize));
- }
- }
- }
- this._viewport.setRenderedRange(newRange);
- this._viewport.setRenderedContentOffset(this._itemSize * newRange.start);
- this._scrolledIndexChange.next(Math.floor(firstVisibleIndex));
- };
- return FixedSizeVirtualScrollStrategy;
- }());
- /**
- * Provider factory for `FixedSizeVirtualScrollStrategy` that simply extracts the already created
- * `FixedSizeVirtualScrollStrategy` from the given directive.
- * @param {?} fixedSizeDir The instance of `CdkFixedSizeVirtualScroll` to extract the
- * `FixedSizeVirtualScrollStrategy` from.
- * @return {?}
- */
- function _fixedSizeVirtualScrollStrategyFactory(fixedSizeDir) {
- return fixedSizeDir._scrollStrategy;
- }
- /**
- * A virtual scroll strategy that supports fixed-size items.
- */
- var CdkFixedSizeVirtualScroll = /** @class */ (function () {
- function CdkFixedSizeVirtualScroll() {
- this._itemSize = 20;
- this._minBufferPx = 100;
- this._maxBufferPx = 200;
- /**
- * The scroll strategy used by this directive.
- */
- this._scrollStrategy = new FixedSizeVirtualScrollStrategy(this.itemSize, this.minBufferPx, this.maxBufferPx);
- }
- Object.defineProperty(CdkFixedSizeVirtualScroll.prototype, "itemSize", {
- /** The size of the items in the list (in pixels). */
- get: /**
- * The size of the items in the list (in pixels).
- * @return {?}
- */
- function () { return this._itemSize; },
- set: /**
- * @param {?} value
- * @return {?}
- */
- function (value) { this._itemSize = coerceNumberProperty(value); },
- enumerable: true,
- configurable: true
- });
- Object.defineProperty(CdkFixedSizeVirtualScroll.prototype, "minBufferPx", {
- /**
- * The minimum amount of buffer rendered beyond the viewport (in pixels).
- * If the amount of buffer dips below this number, more items will be rendered. Defaults to 100px.
- */
- get: /**
- * The minimum amount of buffer rendered beyond the viewport (in pixels).
- * If the amount of buffer dips below this number, more items will be rendered. Defaults to 100px.
- * @return {?}
- */
- function () { return this._minBufferPx; },
- set: /**
- * @param {?} value
- * @return {?}
- */
- function (value) { this._minBufferPx = coerceNumberProperty(value); },
- enumerable: true,
- configurable: true
- });
- Object.defineProperty(CdkFixedSizeVirtualScroll.prototype, "maxBufferPx", {
- /**
- * The number of pixels worth of buffer to render for when rendering new items. Defaults to 200px.
- */
- get: /**
- * The number of pixels worth of buffer to render for when rendering new items. Defaults to 200px.
- * @return {?}
- */
- function () { return this._maxBufferPx; },
- set: /**
- * @param {?} value
- * @return {?}
- */
- function (value) { this._maxBufferPx = coerceNumberProperty(value); },
- enumerable: true,
- configurable: true
- });
- /**
- * @return {?}
- */
- CdkFixedSizeVirtualScroll.prototype.ngOnChanges = /**
- * @return {?}
- */
- function () {
- this._scrollStrategy.updateItemAndBufferSize(this.itemSize, this.minBufferPx, this.maxBufferPx);
- };
- CdkFixedSizeVirtualScroll.decorators = [
- { type: Directive, args: [{
- selector: 'cdk-virtual-scroll-viewport[itemSize]',
- providers: [{
- provide: VIRTUAL_SCROLL_STRATEGY,
- useFactory: _fixedSizeVirtualScrollStrategyFactory,
- deps: [forwardRef((/**
- * @return {?}
- */
- function () { return CdkFixedSizeVirtualScroll; }))],
- }],
- },] },
- ];
- CdkFixedSizeVirtualScroll.propDecorators = {
- itemSize: [{ type: Input }],
- minBufferPx: [{ type: Input }],
- maxBufferPx: [{ type: Input }]
- };
- return CdkFixedSizeVirtualScroll;
- }());
- /**
- * @fileoverview added by tsickle
- * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
- */
- /**
- * Time in ms to throttle the scrolling events by default.
- * @type {?}
- */
- var DEFAULT_SCROLL_TIME = 20;
- /**
- * Service contained all registered Scrollable references and emits an event when any one of the
- * Scrollable references emit a scrolled event.
- */
- var ScrollDispatcher = /** @class */ (function () {
- function ScrollDispatcher(_ngZone, _platform) {
- this._ngZone = _ngZone;
- this._platform = _platform;
- /**
- * Subject for notifying that a registered scrollable reference element has been scrolled.
- */
- this._scrolled = new Subject();
- /**
- * Keeps track of the global `scroll` and `resize` subscriptions.
- */
- this._globalSubscription = null;
- /**
- * Keeps track of the amount of subscriptions to `scrolled`. Used for cleaning up afterwards.
- */
- this._scrolledCount = 0;
- /**
- * Map of all the scrollable references that are registered with the service and their
- * scroll event subscriptions.
- */
- this.scrollContainers = new Map();
- }
- /**
- * Registers a scrollable instance with the service and listens for its scrolled events. When the
- * scrollable is scrolled, the service emits the event to its scrolled observable.
- * @param scrollable Scrollable instance to be registered.
- */
- /**
- * Registers a scrollable instance with the service and listens for its scrolled events. When the
- * scrollable is scrolled, the service emits the event to its scrolled observable.
- * @param {?} scrollable Scrollable instance to be registered.
- * @return {?}
- */
- ScrollDispatcher.prototype.register = /**
- * Registers a scrollable instance with the service and listens for its scrolled events. When the
- * scrollable is scrolled, the service emits the event to its scrolled observable.
- * @param {?} scrollable Scrollable instance to be registered.
- * @return {?}
- */
- function (scrollable) {
- var _this = this;
- if (!this.scrollContainers.has(scrollable)) {
- this.scrollContainers.set(scrollable, scrollable.elementScrolled()
- .subscribe((/**
- * @return {?}
- */
- function () { return _this._scrolled.next(scrollable); })));
- }
- };
- /**
- * Deregisters a Scrollable reference and unsubscribes from its scroll event observable.
- * @param scrollable Scrollable instance to be deregistered.
- */
- /**
- * Deregisters a Scrollable reference and unsubscribes from its scroll event observable.
- * @param {?} scrollable Scrollable instance to be deregistered.
- * @return {?}
- */
- ScrollDispatcher.prototype.deregister = /**
- * Deregisters a Scrollable reference and unsubscribes from its scroll event observable.
- * @param {?} scrollable Scrollable instance to be deregistered.
- * @return {?}
- */
- function (scrollable) {
- /** @type {?} */
- var scrollableReference = this.scrollContainers.get(scrollable);
- if (scrollableReference) {
- scrollableReference.unsubscribe();
- this.scrollContainers.delete(scrollable);
- }
- };
- /**
- * Returns an observable that emits an event whenever any of the registered Scrollable
- * references (or window, document, or body) fire a scrolled event. Can provide a time in ms
- * to override the default "throttle" time.
- *
- * **Note:** in order to avoid hitting change detection for every scroll event,
- * all of the events emitted from this stream will be run outside the Angular zone.
- * If you need to update any data bindings as a result of a scroll event, you have
- * to run the callback using `NgZone.run`.
- */
- /**
- * Returns an observable that emits an event whenever any of the registered Scrollable
- * references (or window, document, or body) fire a scrolled event. Can provide a time in ms
- * to override the default "throttle" time.
- *
- * **Note:** in order to avoid hitting change detection for every scroll event,
- * all of the events emitted from this stream will be run outside the Angular zone.
- * If you need to update any data bindings as a result of a scroll event, you have
- * to run the callback using `NgZone.run`.
- * @param {?=} auditTimeInMs
- * @return {?}
- */
- ScrollDispatcher.prototype.scrolled = /**
- * Returns an observable that emits an event whenever any of the registered Scrollable
- * references (or window, document, or body) fire a scrolled event. Can provide a time in ms
- * to override the default "throttle" time.
- *
- * **Note:** in order to avoid hitting change detection for every scroll event,
- * all of the events emitted from this stream will be run outside the Angular zone.
- * If you need to update any data bindings as a result of a scroll event, you have
- * to run the callback using `NgZone.run`.
- * @param {?=} auditTimeInMs
- * @return {?}
- */
- function (auditTimeInMs) {
- var _this = this;
- if (auditTimeInMs === void 0) { auditTimeInMs = DEFAULT_SCROLL_TIME; }
- if (!this._platform.isBrowser) {
- return of();
- }
- return new Observable((/**
- * @param {?} observer
- * @return {?}
- */
- function (observer) {
- if (!_this._globalSubscription) {
- _this._addGlobalListener();
- }
- // In the case of a 0ms delay, use an observable without auditTime
- // since it does add a perceptible delay in processing overhead.
- /** @type {?} */
- var subscription = auditTimeInMs > 0 ?
- _this._scrolled.pipe(auditTime(auditTimeInMs)).subscribe(observer) :
- _this._scrolled.subscribe(observer);
- _this._scrolledCount++;
- return (/**
- * @return {?}
- */
- function () {
- subscription.unsubscribe();
- _this._scrolledCount--;
- if (!_this._scrolledCount) {
- _this._removeGlobalListener();
- }
- });
- }));
- };
- /**
- * @return {?}
- */
- ScrollDispatcher.prototype.ngOnDestroy = /**
- * @return {?}
- */
- function () {
- var _this = this;
- this._removeGlobalListener();
- this.scrollContainers.forEach((/**
- * @param {?} _
- * @param {?} container
- * @return {?}
- */
- function (_, container) { return _this.deregister(container); }));
- this._scrolled.complete();
- };
- /**
- * Returns an observable that emits whenever any of the
- * scrollable ancestors of an element are scrolled.
- * @param elementRef Element whose ancestors to listen for.
- * @param auditTimeInMs Time to throttle the scroll events.
- */
- /**
- * Returns an observable that emits whenever any of the
- * scrollable ancestors of an element are scrolled.
- * @param {?} elementRef Element whose ancestors to listen for.
- * @param {?=} auditTimeInMs Time to throttle the scroll events.
- * @return {?}
- */
- ScrollDispatcher.prototype.ancestorScrolled = /**
- * Returns an observable that emits whenever any of the
- * scrollable ancestors of an element are scrolled.
- * @param {?} elementRef Element whose ancestors to listen for.
- * @param {?=} auditTimeInMs Time to throttle the scroll events.
- * @return {?}
- */
- function (elementRef, auditTimeInMs) {
- /** @type {?} */
- var ancestors = this.getAncestorScrollContainers(elementRef);
- return this.scrolled(auditTimeInMs).pipe(filter((/**
- * @param {?} target
- * @return {?}
- */
- function (target) {
- return !target || ancestors.indexOf(target) > -1;
- })));
- };
- /** Returns all registered Scrollables that contain the provided element. */
- /**
- * Returns all registered Scrollables that contain the provided element.
- * @param {?} elementRef
- * @return {?}
- */
- ScrollDispatcher.prototype.getAncestorScrollContainers = /**
- * Returns all registered Scrollables that contain the provided element.
- * @param {?} elementRef
- * @return {?}
- */
- function (elementRef) {
- var _this = this;
- /** @type {?} */
- var scrollingContainers = [];
- this.scrollContainers.forEach((/**
- * @param {?} _subscription
- * @param {?} scrollable
- * @return {?}
- */
- function (_subscription, scrollable) {
- if (_this._scrollableContainsElement(scrollable, elementRef)) {
- scrollingContainers.push(scrollable);
- }
- }));
- return scrollingContainers;
- };
- /** Returns true if the element is contained within the provided Scrollable. */
- /**
- * Returns true if the element is contained within the provided Scrollable.
- * @private
- * @param {?} scrollable
- * @param {?} elementRef
- * @return {?}
- */
- ScrollDispatcher.prototype._scrollableContainsElement = /**
- * Returns true if the element is contained within the provided Scrollable.
- * @private
- * @param {?} scrollable
- * @param {?} elementRef
- * @return {?}
- */
- function (scrollable, elementRef) {
- /** @type {?} */
- var element = elementRef.nativeElement;
- /** @type {?} */
- var scrollableElement = scrollable.getElementRef().nativeElement;
- // Traverse through the element parents until we reach null, checking if any of the elements
- // are the scrollable's element.
- do {
- if (element == scrollableElement) {
- return true;
- }
- } while (element = (/** @type {?} */ (element)).parentElement);
- return false;
- };
- /** Sets up the global scroll listeners. */
- /**
- * Sets up the global scroll listeners.
- * @private
- * @return {?}
- */
- ScrollDispatcher.prototype._addGlobalListener = /**
- * Sets up the global scroll listeners.
- * @private
- * @return {?}
- */
- function () {
- var _this = this;
- this._globalSubscription = this._ngZone.runOutsideAngular((/**
- * @return {?}
- */
- function () {
- return fromEvent(window.document, 'scroll').subscribe((/**
- * @return {?}
- */
- function () { return _this._scrolled.next(); }));
- }));
- };
- /** Cleans up the global scroll listener. */
- /**
- * Cleans up the global scroll listener.
- * @private
- * @return {?}
- */
- ScrollDispatcher.prototype._removeGlobalListener = /**
- * Cleans up the global scroll listener.
- * @private
- * @return {?}
- */
- function () {
- if (this._globalSubscription) {
- this._globalSubscription.unsubscribe();
- this._globalSubscription = null;
- }
- };
- ScrollDispatcher.decorators = [
- { type: Injectable, args: [{ providedIn: 'root' },] },
- ];
- /** @nocollapse */
- ScrollDispatcher.ctorParameters = function () { return [
- { type: NgZone },
- { type: Platform }
- ]; };
- /** @nocollapse */ ScrollDispatcher.ngInjectableDef = ɵɵdefineInjectable({ factory: function ScrollDispatcher_Factory() { return new ScrollDispatcher(ɵɵinject(NgZone), ɵɵinject(Platform)); }, token: ScrollDispatcher, providedIn: "root" });
- return ScrollDispatcher;
- }());
- /**
- * \@docs-private \@deprecated \@breaking-change 8.0.0
- * @param {?} parentDispatcher
- * @param {?} ngZone
- * @param {?} platform
- * @return {?}
- */
- function SCROLL_DISPATCHER_PROVIDER_FACTORY(parentDispatcher, ngZone, platform) {
- return parentDispatcher || new ScrollDispatcher(ngZone, platform);
- }
- /**
- * \@docs-private \@deprecated \@breaking-change 8.0.0
- * @type {?}
- */
- var SCROLL_DISPATCHER_PROVIDER = {
- // If there is already a ScrollDispatcher available, use that. Otherwise, provide a new one.
- provide: ScrollDispatcher,
- deps: [[new Optional(), new SkipSelf(), ScrollDispatcher], NgZone, Platform],
- useFactory: SCROLL_DISPATCHER_PROVIDER_FACTORY
- };
- /**
- * @fileoverview added by tsickle
- * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
- */
- /**
- * Sends an event when the directive's element is scrolled. Registers itself with the
- * ScrollDispatcher service to include itself as part of its collection of scrolling events that it
- * can be listened to through the service.
- */
- var CdkScrollable = /** @class */ (function () {
- function CdkScrollable(elementRef, scrollDispatcher, ngZone, dir) {
- var _this = this;
- this.elementRef = elementRef;
- this.scrollDispatcher = scrollDispatcher;
- this.ngZone = ngZone;
- this.dir = dir;
- this._destroyed = new Subject();
- this._elementScrolled = new Observable((/**
- * @param {?} observer
- * @return {?}
- */
- function (observer) {
- return _this.ngZone.runOutsideAngular((/**
- * @return {?}
- */
- function () {
- return fromEvent(_this.elementRef.nativeElement, 'scroll').pipe(takeUntil(_this._destroyed))
- .subscribe(observer);
- }));
- }));
- }
- /**
- * @return {?}
- */
- CdkScrollable.prototype.ngOnInit = /**
- * @return {?}
- */
- function () {
- this.scrollDispatcher.register(this);
- };
- /**
- * @return {?}
- */
- CdkScrollable.prototype.ngOnDestroy = /**
- * @return {?}
- */
- function () {
- this.scrollDispatcher.deregister(this);
- this._destroyed.next();
- this._destroyed.complete();
- };
- /** Returns observable that emits when a scroll event is fired on the host element. */
- /**
- * Returns observable that emits when a scroll event is fired on the host element.
- * @return {?}
- */
- CdkScrollable.prototype.elementScrolled = /**
- * Returns observable that emits when a scroll event is fired on the host element.
- * @return {?}
- */
- function () {
- return this._elementScrolled;
- };
- /** Gets the ElementRef for the viewport. */
- /**
- * Gets the ElementRef for the viewport.
- * @return {?}
- */
- CdkScrollable.prototype.getElementRef = /**
- * Gets the ElementRef for the viewport.
- * @return {?}
- */
- function () {
- return this.elementRef;
- };
- /**
- * Scrolls to the specified offsets. This is a normalized version of the browser's native scrollTo
- * method, since browsers are not consistent about what scrollLeft means in RTL. For this method
- * left and right always refer to the left and right side of the scrolling container irrespective
- * of the layout direction. start and end refer to left and right in an LTR context and vice-versa
- * in an RTL context.
- * @param options specified the offsets to scroll to.
- */
- /**
- * Scrolls to the specified offsets. This is a normalized version of the browser's native scrollTo
- * method, since browsers are not consistent about what scrollLeft means in RTL. For this method
- * left and right always refer to the left and right side of the scrolling container irrespective
- * of the layout direction. start and end refer to left and right in an LTR context and vice-versa
- * in an RTL context.
- * @param {?} options specified the offsets to scroll to.
- * @return {?}
- */
- CdkScrollable.prototype.scrollTo = /**
- * Scrolls to the specified offsets. This is a normalized version of the browser's native scrollTo
- * method, since browsers are not consistent about what scrollLeft means in RTL. For this method
- * left and right always refer to the left and right side of the scrolling container irrespective
- * of the layout direction. start and end refer to left and right in an LTR context and vice-versa
- * in an RTL context.
- * @param {?} options specified the offsets to scroll to.
- * @return {?}
- */
- function (options) {
- /** @type {?} */
- var el = this.elementRef.nativeElement;
- /** @type {?} */
- var isRtl = this.dir && this.dir.value == 'rtl';
- // Rewrite start & end offsets as right or left offsets.
- options.left = options.left == null ? (isRtl ? options.end : options.start) : options.left;
- options.right = options.right == null ? (isRtl ? options.start : options.end) : options.right;
- // Rewrite the bottom offset as a top offset.
- if (options.bottom != null) {
- ((/** @type {?} */ (options))).top =
- el.scrollHeight - el.clientHeight - options.bottom;
- }
- // Rewrite the right offset as a left offset.
- if (isRtl && getRtlScrollAxisType() != RtlScrollAxisType.NORMAL) {
- if (options.left != null) {
- ((/** @type {?} */ (options))).right =
- el.scrollWidth - el.clientWidth - options.left;
- }
- if (getRtlScrollAxisType() == RtlScrollAxisType.INVERTED) {
- options.left = options.right;
- }
- else if (getRtlScrollAxisType() == RtlScrollAxisType.NEGATED) {
- options.left = options.right ? -options.right : options.right;
- }
- }
- else {
- if (options.right != null) {
- ((/** @type {?} */ (options))).left =
- el.scrollWidth - el.clientWidth - options.right;
- }
- }
- this._applyScrollToOptions(options);
- };
- /**
- * @private
- * @param {?} options
- * @return {?}
- */
- CdkScrollable.prototype._applyScrollToOptions = /**
- * @private
- * @param {?} options
- * @return {?}
- */
- function (options) {
- /** @type {?} */
- var el = this.elementRef.nativeElement;
- if (supportsScrollBehavior()) {
- el.scrollTo(options);
- }
- else {
- if (options.top != null) {
- el.scrollTop = options.top;
- }
- if (options.left != null) {
- el.scrollLeft = options.left;
- }
- }
- };
- /**
- * Measures the scroll offset relative to the specified edge of the viewport. This method can be
- * used instead of directly checking scrollLeft or scrollTop, since browsers are not consistent
- * about what scrollLeft means in RTL. The values returned by this method are normalized such that
- * left and right always refer to the left and right side of the scrolling container irrespective
- * of the layout direction. start and end refer to left and right in an LTR context and vice-versa
- * in an RTL context.
- * @param from The edge to measure from.
- */
- /**
- * Measures the scroll offset relative to the specified edge of the viewport. This method can be
- * used instead of directly checking scrollLeft or scrollTop, since browsers are not consistent
- * about what scrollLeft means in RTL. The values returned by this method are normalized such that
- * left and right always refer to the left and right side of the scrolling container irrespective
- * of the layout direction. start and end refer to left and right in an LTR context and vice-versa
- * in an RTL context.
- * @param {?} from The edge to measure from.
- * @return {?}
- */
- CdkScrollable.prototype.measureScrollOffset = /**
- * Measures the scroll offset relative to the specified edge of the viewport. This method can be
- * used instead of directly checking scrollLeft or scrollTop, since browsers are not consistent
- * about what scrollLeft means in RTL. The values returned by this method are normalized such that
- * left and right always refer to the left and right side of the scrolling container irrespective
- * of the layout direction. start and end refer to left and right in an LTR context and vice-versa
- * in an RTL context.
- * @param {?} from The edge to measure from.
- * @return {?}
- */
- function (from) {
- /** @type {?} */
- var LEFT = 'left';
- /** @type {?} */
- var RIGHT = 'right';
- /** @type {?} */
- var el = this.elementRef.nativeElement;
- if (from == 'top') {
- return el.scrollTop;
- }
- if (from == 'bottom') {
- return el.scrollHeight - el.clientHeight - el.scrollTop;
- }
- // Rewrite start & end as left or right offsets.
- /** @type {?} */
- var isRtl = this.dir && this.dir.value == 'rtl';
- if (from == 'start') {
- from = isRtl ? RIGHT : LEFT;
- }
- else if (from == 'end') {
- from = isRtl ? LEFT : RIGHT;
- }
- if (isRtl && getRtlScrollAxisType() == RtlScrollAxisType.INVERTED) {
- // For INVERTED, scrollLeft is (scrollWidth - clientWidth) when scrolled all the way left and
- // 0 when scrolled all the way right.
- if (from == LEFT) {
- return el.scrollWidth - el.clientWidth - el.scrollLeft;
- }
- else {
- return el.scrollLeft;
- }
- }
- else if (isRtl && getRtlScrollAxisType() == RtlScrollAxisType.NEGATED) {
- // For NEGATED, scrollLeft is -(scrollWidth - clientWidth) when scrolled all the way left and
- // 0 when scrolled all the way right.
- if (from == LEFT) {
- return el.scrollLeft + el.scrollWidth - el.clientWidth;
- }
- else {
- return -el.scrollLeft;
- }
- }
- else {
- // For NORMAL, as well as non-RTL contexts, scrollLeft is 0 when scrolled all the way left and
- // (scrollWidth - clientWidth) when scrolled all the way right.
- if (from == LEFT) {
- return el.scrollLeft;
- }
- else {
- return el.scrollWidth - el.clientWidth - el.scrollLeft;
- }
- }
- };
- CdkScrollable.decorators = [
- { type: Directive, args: [{
- selector: '[cdk-scrollable], [cdkScrollable]'
- },] },
- ];
- /** @nocollapse */
- CdkScrollable.ctorParameters = function () { return [
- { type: ElementRef },
- { type: ScrollDispatcher },
- { type: NgZone },
- { type: Directionality, decorators: [{ type: Optional }] }
- ]; };
- return CdkScrollable;
- }());
- /**
- * @fileoverview added by tsickle
- * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
- */
- /**
- * Checks if the given ranges are equal.
- * @param {?} r1
- * @param {?} r2
- * @return {?}
- */
- function rangesEqual(r1, r2) {
- return r1.start == r2.start && r1.end == r2.end;
- }
- /**
- * Scheduler to be used for scroll events. Needs to fall back to
- * something that doesn't rely on requestAnimationFrame on environments
- * that don't support it (e.g. server-side rendering).
- * @type {?}
- */
- var SCROLL_SCHEDULER = typeof requestAnimationFrame !== 'undefined' ? animationFrameScheduler : asapScheduler;
- /**
- * A viewport that virtualizes its scrolling with the help of `CdkVirtualForOf`.
- */
- var CdkVirtualScrollViewport = /** @class */ (function (_super) {
- __extends(CdkVirtualScrollViewport, _super);
- function CdkVirtualScrollViewport(elementRef, _changeDetectorRef, ngZone, _scrollStrategy, dir, scrollDispatcher) {
- var _this = _super.call(this, elementRef, scrollDispatcher, ngZone, dir) || this;
- _this.elementRef = elementRef;
- _this._changeDetectorRef = _changeDetectorRef;
- _this._scrollStrategy = _scrollStrategy;
- /**
- * Emits when the viewport is detached from a CdkVirtualForOf.
- */
- _this._detachedSubject = new Subject();
- /**
- * Emits when the rendered range changes.
- */
- _this._renderedRangeSubject = new Subject();
- _this._orientation = 'vertical';
- // Note: we don't use the typical EventEmitter here because we need to subscribe to the scroll
- // strategy lazily (i.e. only if the user is actually listening to the events). We do this because
- // depending on how the strategy calculates the scrolled index, it may come at a cost to
- // performance.
- /**
- * Emits when the index of the first element visible in the viewport changes.
- */
- _this.scrolledIndexChange = new Observable((/**
- * @param {?} observer
- * @return {?}
- */
- function (observer) {
- return _this._scrollStrategy.scrolledIndexChange.subscribe((/**
- * @param {?} index
- * @return {?}
- */
- function (index) {
- return Promise.resolve().then((/**
- * @return {?}
- */
- function () { return _this.ngZone.run((/**
- * @return {?}
- */
- function () { return observer.next(index); })); }));
- }));
- }));
- /**
- * A stream that emits whenever the rendered range changes.
- */
- _this.renderedRangeStream = _this._renderedRangeSubject.asObservable();
- /**
- * The total size of all content (in pixels), including content that is not currently rendered.
- */
- _this._totalContentSize = 0;
- /**
- * A string representing the `style.width` property value to be used for the spacer element.
- */
- _this._totalContentWidth = '';
- /**
- * A string representing the `style.height` property value to be used for the spacer element.
- */
- _this._totalContentHeight = '';
- /**
- * The currently rendered range of indices.
- */
- _this._renderedRange = { start: 0, end: 0 };
- /**
- * The length of the data bound to this viewport (in number of items).
- */
- _this._dataLength = 0;
- /**
- * The size of the viewport (in pixels).
- */
- _this._viewportSize = 0;
- /**
- * The last rendered content offset that was set.
- */
- _this._renderedContentOffset = 0;
- /**
- * Whether the last rendered content offset was to the end of the content (and therefore needs to
- * be rewritten as an offset to the start of the content).
- */
- _this._renderedContentOffsetNeedsRewrite = false;
- /**
- * Whether there is a pending change detection cycle.
- */
- _this._isChangeDetectionPending = false;
- /**
- * A list of functions to run after the next change detection cycle.
- */
- _this._runAfterChangeDetection = [];
- if (!_scrollStrategy) {
- throw Error('Error: cdk-virtual-scroll-viewport requires the "itemSize" property to be set.');
- }
- return _this;
- }
- Object.defineProperty(CdkVirtualScrollViewport.prototype, "orientation", {
- /** The direction the viewport scrolls. */
- get: /**
- * The direction the viewport scrolls.
- * @return {?}
- */
- function () {
- return this._orientation;
- },
- set: /**
- * @param {?} orientation
- * @return {?}
- */
- function (orientation) {
- if (this._orientation !== orientation) {
- this._orientation = orientation;
- this._calculateSpacerSize();
- }
- },
- enumerable: true,
- configurable: true
- });
- /**
- * @return {?}
- */
- CdkVirtualScrollViewport.prototype.ngOnInit = /**
- * @return {?}
- */
- function () {
- var _this = this;
- _super.prototype.ngOnInit.call(this);
- // It's still too early to measure the viewport at this point. Deferring with a promise allows
- // the Viewport to be rendered with the correct size before we measure. We run this outside the
- // zone to avoid causing more change detection cycles. We handle the change detection loop
- // ourselves instead.
- this.ngZone.runOutsideAngular((/**
- * @return {?}
- */
- function () { return Promise.resolve().then((/**
- * @return {?}
- */
- function () {
- _this._measureViewportSize();
- _this._scrollStrategy.attach(_this);
- _this.elementScrolled()
- .pipe(
- // Start off with a fake scroll event so we properly detect our initial position.
- startWith((/** @type {?} */ (null))),
- // Collect multiple events into one until the next animation frame. This way if
- // there are multiple scroll events in the same frame we only need to recheck
- // our layout once.
- auditTime(0, SCROLL_SCHEDULER))
- .subscribe((/**
- * @return {?}
- */
- function () { return _this._scrollStrategy.onContentScrolled(); }));
- _this._markChangeDetectionNeeded();
- })); }));
- };
- /**
- * @return {?}
- */
- CdkVirtualScrollViewport.prototype.ngOnDestroy = /**
- * @return {?}
- */
- function () {
- this.detach();
- this._scrollStrategy.detach();
- // Complete all subjects
- this._renderedRangeSubject.complete();
- this._detachedSubject.complete();
- _super.prototype.ngOnDestroy.call(this);
- };
- /** Attaches a `CdkVirtualForOf` to this viewport. */
- /**
- * Attaches a `CdkVirtualForOf` to this viewport.
- * @param {?} forOf
- * @return {?}
- */
- CdkVirtualScrollViewport.prototype.attach = /**
- * Attaches a `CdkVirtualForOf` to this viewport.
- * @param {?} forOf
- * @return {?}
- */
- function (forOf) {
- var _this = this;
- if (this._forOf) {
- throw Error('CdkVirtualScrollViewport is already attached.');
- }
- // Subscribe to the data stream of the CdkVirtualForOf to keep track of when the data length
- // changes. Run outside the zone to avoid triggering change detection, since we're managing the
- // change detection loop ourselves.
- this.ngZone.runOutsideAngular((/**
- * @return {?}
- */
- function () {
- _this._forOf = forOf;
- _this._forOf.dataStream.pipe(takeUntil(_this._detachedSubject)).subscribe((/**
- * @param {?} data
- * @return {?}
- */
- function (data) {
- /** @type {?} */
- var newLength = data.length;
- if (newLength !== _this._dataLength) {
- _this._dataLength = newLength;
- _this._scrollStrategy.onDataLengthChanged();
- }
- _this._doChangeDetection();
- }));
- }));
- };
- /** Detaches the current `CdkVirtualForOf`. */
- /**
- * Detaches the current `CdkVirtualForOf`.
- * @return {?}
- */
- CdkVirtualScrollViewport.prototype.detach = /**
- * Detaches the current `CdkVirtualForOf`.
- * @return {?}
- */
- function () {
- this._forOf = null;
- this._detachedSubject.next();
- };
- /** Gets the length of the data bound to this viewport (in number of items). */
- /**
- * Gets the length of the data bound to this viewport (in number of items).
- * @return {?}
- */
- CdkVirtualScrollViewport.prototype.getDataLength = /**
- * Gets the length of the data bound to this viewport (in number of items).
- * @return {?}
- */
- function () {
- return this._dataLength;
- };
- /** Gets the size of the viewport (in pixels). */
- /**
- * Gets the size of the viewport (in pixels).
- * @return {?}
- */
- CdkVirtualScrollViewport.prototype.getViewportSize = /**
- * Gets the size of the viewport (in pixels).
- * @return {?}
- */
- function () {
- return this._viewportSize;
- };
- // TODO(mmalerba): This is technically out of sync with what's really rendered until a render
- // cycle happens. I'm being careful to only call it after the render cycle is complete and before
- // setting it to something else, but its error prone and should probably be split into
- // `pendingRange` and `renderedRange`, the latter reflecting whats actually in the DOM.
- /** Get the current rendered range of items. */
- // TODO(mmalerba): This is technically out of sync with what's really rendered until a render
- // cycle happens. I'm being careful to only call it after the render cycle is complete and before
- // setting it to something else, but its error prone and should probably be split into
- // `pendingRange` and `renderedRange`, the latter reflecting whats actually in the DOM.
- /**
- * Get the current rendered range of items.
- * @return {?}
- */
- CdkVirtualScrollViewport.prototype.getRenderedRange =
- // TODO(mmalerba): This is technically out of sync with what's really rendered until a render
- // cycle happens. I'm being careful to only call it after the render cycle is complete and before
- // setting it to something else, but its error prone and should probably be split into
- // `pendingRange` and `renderedRange`, the latter reflecting whats actually in the DOM.
- /**
- * Get the current rendered range of items.
- * @return {?}
- */
- function () {
- return this._renderedRange;
- };
- /**
- * Sets the total size of all content (in pixels), including content that is not currently
- * rendered.
- */
- /**
- * Sets the total size of all content (in pixels), including content that is not currently
- * rendered.
- * @param {?} size
- * @return {?}
- */
- CdkVirtualScrollViewport.prototype.setTotalContentSize = /**
- * Sets the total size of all content (in pixels), including content that is not currently
- * rendered.
- * @param {?} size
- * @return {?}
- */
- function (size) {
- if (this._totalContentSize !== size) {
- this._totalContentSize = size;
- this._calculateSpacerSize();
- this._markChangeDetectionNeeded();
- }
- };
- /** Sets the currently rendered range of indices. */
- /**
- * Sets the currently rendered range of indices.
- * @param {?} range
- * @return {?}
- */
- CdkVirtualScrollViewport.prototype.setRenderedRange = /**
- * Sets the currently rendered range of indices.
- * @param {?} range
- * @return {?}
- */
- function (range) {
- var _this = this;
- if (!rangesEqual(this._renderedRange, range)) {
- this._renderedRangeSubject.next(this._renderedRange = range);
- this._markChangeDetectionNeeded((/**
- * @return {?}
- */
- function () { return _this._scrollStrategy.onContentRendered(); }));
- }
- };
- /**
- * Gets the offset from the start of the viewport to the start of the rendered data (in pixels).
- */
- /**
- * Gets the offset from the start of the viewport to the start of the rendered data (in pixels).
- * @return {?}
- */
- CdkVirtualScrollViewport.prototype.getOffsetToRenderedContentStart = /**
- * Gets the offset from the start of the viewport to the start of the rendered data (in pixels).
- * @return {?}
- */
- function () {
- return this._renderedContentOffsetNeedsRewrite ? null : this._renderedContentOffset;
- };
- /**
- * Sets the offset from the start of the viewport to either the start or end of the rendered data
- * (in pixels).
- */
- /**
- * Sets the offset from the start of the viewport to either the start or end of the rendered data
- * (in pixels).
- * @param {?} offset
- * @param {?=} to
- * @return {?}
- */
- CdkVirtualScrollViewport.prototype.setRenderedContentOffset = /**
- * Sets the offset from the start of the viewport to either the start or end of the rendered data
- * (in pixels).
- * @param {?} offset
- * @param {?=} to
- * @return {?}
- */
- function (offset, to) {
- var _this = this;
- if (to === void 0) { to = 'to-start'; }
- // For a horizontal viewport in a right-to-left language we need to translate along the x-axis
- // in the negative direction.
- /** @type {?} */
- var isRtl = this.dir && this.dir.value == 'rtl';
- /** @type {?} */
- var isHorizontal = this.orientation == 'horizontal';
- /** @type {?} */
- var axis = isHorizontal ? 'X' : 'Y';
- /** @type {?} */
- var axisDirection = isHorizontal && isRtl ? -1 : 1;
- /** @type {?} */
- var transform = "translate" + axis + "(" + Number(axisDirection * offset) + "px)";
- this._renderedContentOffset = offset;
- if (to === 'to-end') {
- transform += " translate" + axis + "(-100%)";
- // The viewport should rewrite this as a `to-start` offset on the next render cycle. Otherwise
- // elements will appear to expand in the wrong direction (e.g. `mat-expansion-panel` would
- // expand upward).
- this._renderedContentOffsetNeedsRewrite = true;
- }
- if (this._renderedContentTransform != transform) {
- // We know this value is safe because we parse `offset` with `Number()` before passing it
- // into the string.
- this._renderedContentTransform = transform;
- this._markChangeDetectionNeeded((/**
- * @return {?}
- */
- function () {
- if (_this._renderedContentOffsetNeedsRewrite) {
- _this._renderedContentOffset -= _this.measureRenderedContentSize();
- _this._renderedContentOffsetNeedsRewrite = false;
- _this.setRenderedContentOffset(_this._renderedContentOffset);
- }
- else {
- _this._scrollStrategy.onRenderedOffsetChanged();
- }
- }));
- }
- };
- /**
- * Scrolls to the given offset from the start of the viewport. Please note that this is not always
- * the same as setting `scrollTop` or `scrollLeft`. In a horizontal viewport with right-to-left
- * direction, this would be the equivalent of setting a fictional `scrollRight` property.
- * @param offset The offset to scroll to.
- * @param behavior The ScrollBehavior to use when scrolling. Default is behavior is `auto`.
- */
- /**
- * Scrolls to the given offset from the start of the viewport. Please note that this is not always
- * the same as setting `scrollTop` or `scrollLeft`. In a horizontal viewport with right-to-left
- * direction, this would be the equivalent of setting a fictional `scrollRight` property.
- * @param {?} offset The offset to scroll to.
- * @param {?=} behavior The ScrollBehavior to use when scrolling. Default is behavior is `auto`.
- * @return {?}
- */
- CdkVirtualScrollViewport.prototype.scrollToOffset = /**
- * Scrolls to the given offset from the start of the viewport. Please note that this is not always
- * the same as setting `scrollTop` or `scrollLeft`. In a horizontal viewport with right-to-left
- * direction, this would be the equivalent of setting a fictional `scrollRight` property.
- * @param {?} offset The offset to scroll to.
- * @param {?=} behavior The ScrollBehavior to use when scrolling. Default is behavior is `auto`.
- * @return {?}
- */
- function (offset, behavior) {
- if (behavior === void 0) { behavior = 'auto'; }
- /** @type {?} */
- var options = { behavior: behavior };
- if (this.orientation === 'horizontal') {
- options.start = offset;
- }
- else {
- options.top = offset;
- }
- this.scrollTo(options);
- };
- /**
- * Scrolls to the offset for the given index.
- * @param index The index of the element to scroll to.
- * @param behavior The ScrollBehavior to use when scrolling. Default is behavior is `auto`.
- */
- /**
- * Scrolls to the offset for the given index.
- * @param {?} index The index of the element to scroll to.
- * @param {?=} behavior The ScrollBehavior to use when scrolling. Default is behavior is `auto`.
- * @return {?}
- */
- CdkVirtualScrollViewport.prototype.scrollToIndex = /**
- * Scrolls to the offset for the given index.
- * @param {?} index The index of the element to scroll to.
- * @param {?=} behavior The ScrollBehavior to use when scrolling. Default is behavior is `auto`.
- * @return {?}
- */
- function (index, behavior) {
- if (behavior === void 0) { behavior = 'auto'; }
- this._scrollStrategy.scrollToIndex(index, behavior);
- };
- /**
- * Gets the current scroll offset from the start of the viewport (in pixels).
- * @param from The edge to measure the offset from. Defaults to 'top' in vertical mode and 'start'
- * in horizontal mode.
- */
- /**
- * Gets the current scroll offset from the start of the viewport (in pixels).
- * @param {?=} from The edge to measure the offset from. Defaults to 'top' in vertical mode and 'start'
- * in horizontal mode.
- * @return {?}
- */
- CdkVirtualScrollViewport.prototype.measureScrollOffset = /**
- * Gets the current scroll offset from the start of the viewport (in pixels).
- * @param {?=} from The edge to measure the offset from. Defaults to 'top' in vertical mode and 'start'
- * in horizontal mode.
- * @return {?}
- */
- function (from) {
- return _super.prototype.measureScrollOffset.call(this, from ? from : this.orientation === 'horizontal' ? 'start' : 'top');
- };
- /** Measure the combined size of all of the rendered items. */
- /**
- * Measure the combined size of all of the rendered items.
- * @return {?}
- */
- CdkVirtualScrollViewport.prototype.measureRenderedContentSize = /**
- * Measure the combined size of all of the rendered items.
- * @return {?}
- */
- function () {
- /** @type {?} */
- var contentEl = this._contentWrapper.nativeElement;
- return this.orientation === 'horizontal' ? contentEl.offsetWidth : contentEl.offsetHeight;
- };
- /**
- * Measure the total combined size of the given range. Throws if the range includes items that are
- * not rendered.
- */
- /**
- * Measure the total combined size of the given range. Throws if the range includes items that are
- * not rendered.
- * @param {?} range
- * @return {?}
- */
- CdkVirtualScrollViewport.prototype.measureRangeSize = /**
- * Measure the total combined size of the given range. Throws if the range includes items that are
- * not rendered.
- * @param {?} range
- * @return {?}
- */
- function (range) {
- if (!this._forOf) {
- return 0;
- }
- return this._forOf.measureRangeSize(range, this.orientation);
- };
- /** Update the viewport dimensions and re-render. */
- /**
- * Update the viewport dimensions and re-render.
- * @return {?}
- */
- CdkVirtualScrollViewport.prototype.checkViewportSize = /**
- * Update the viewport dimensions and re-render.
- * @return {?}
- */
- function () {
- // TODO: Cleanup later when add logic for handling content resize
- this._measureViewportSize();
- this._scrollStrategy.onDataLengthChanged();
- };
- /** Measure the viewport size. */
- /**
- * Measure the viewport size.
- * @private
- * @return {?}
- */
- CdkVirtualScrollViewport.prototype._measureViewportSize = /**
- * Measure the viewport size.
- * @private
- * @return {?}
- */
- function () {
- /** @type {?} */
- var viewportEl = this.elementRef.nativeElement;
- this._viewportSize = this.orientation === 'horizontal' ?
- viewportEl.clientWidth : viewportEl.clientHeight;
- };
- /** Queue up change detection to run. */
- /**
- * Queue up change detection to run.
- * @private
- * @param {?=} runAfter
- * @return {?}
- */
- CdkVirtualScrollViewport.prototype._markChangeDetectionNeeded = /**
- * Queue up change detection to run.
- * @private
- * @param {?=} runAfter
- * @return {?}
- */
- function (runAfter) {
- var _this = this;
- if (runAfter) {
- this._runAfterChangeDetection.push(runAfter);
- }
- // Use a Promise to batch together calls to `_doChangeDetection`. This way if we set a bunch of
- // properties sequentially we only have to run `_doChangeDetection` once at the end.
- if (!this._isChangeDetectionPending) {
- this._isChangeDetectionPending = true;
- this.ngZone.runOutsideAngular((/**
- * @return {?}
- */
- function () { return Promise.resolve().then((/**
- * @return {?}
- */
- function () {
- _this._doChangeDetection();
- })); }));
- }
- };
- /** Run change detection. */
- /**
- * Run change detection.
- * @private
- * @return {?}
- */
- CdkVirtualScrollViewport.prototype._doChangeDetection = /**
- * Run change detection.
- * @private
- * @return {?}
- */
- function () {
- var _this = this;
- this._isChangeDetectionPending = false;
- // Apply changes to Angular bindings. Note: We must call `markForCheck` to run change detection
- // from the root, since the repeated items are content projected in. Calling `detectChanges`
- // instead does not properly check the projected content.
- this.ngZone.run((/**
- * @return {?}
- */
- function () { return _this._changeDetectorRef.markForCheck(); }));
- // Apply the content transform. The transform can't be set via an Angular binding because
- // bypassSecurityTrustStyle is banned in Google. However the value is safe, it's composed of
- // string literals, a variable that can only be 'X' or 'Y', and user input that is run through
- // the `Number` function first to coerce it to a numeric value.
- this._contentWrapper.nativeElement.style.transform = this._renderedContentTransform;
- /** @type {?} */
- var runAfterChangeDetection = this._runAfterChangeDetection;
- this._runAfterChangeDetection = [];
- for (var _i = 0, runAfterChangeDetection_1 = runAfterChangeDetection; _i < runAfterChangeDetection_1.length; _i++) {
- var fn = runAfterChangeDetection_1[_i];
- fn();
- }
- };
- /** Calculates the `style.width` and `style.height` for the spacer element. */
- /**
- * Calculates the `style.width` and `style.height` for the spacer element.
- * @private
- * @return {?}
- */
- CdkVirtualScrollViewport.prototype._calculateSpacerSize = /**
- * Calculates the `style.width` and `style.height` for the spacer element.
- * @private
- * @return {?}
- */
- function () {
- this._totalContentHeight =
- this.orientation === 'horizontal' ? '' : this._totalContentSize + "px";
- this._totalContentWidth =
- this.orientation === 'horizontal' ? this._totalContentSize + "px" : '';
- };
- CdkVirtualScrollViewport.decorators = [
- { type: Component, args: [{selector: 'cdk-virtual-scroll-viewport',
- template: "<div #contentWrapper class=\"cdk-virtual-scroll-content-wrapper\"><ng-content></ng-content></div><div class=\"cdk-virtual-scroll-spacer\" [style.width]=\"_totalContentWidth\" [style.height]=\"_totalContentHeight\"></div>",
- styles: ["cdk-virtual-scroll-viewport{display:block;position:relative;overflow:auto;contain:strict;transform:translateZ(0);will-change:scroll-position;-webkit-overflow-scrolling:touch}.cdk-virtual-scroll-content-wrapper{position:absolute;top:0;left:0;contain:content}[dir=rtl] .cdk-virtual-scroll-content-wrapper{right:0;left:auto}.cdk-virtual-scroll-orientation-horizontal .cdk-virtual-scroll-content-wrapper{min-height:100%}.cdk-virtual-scroll-orientation-horizontal .cdk-virtual-scroll-content-wrapper>dl:not([cdkVirtualFor]),.cdk-virtual-scroll-orientation-horizontal .cdk-virtual-scroll-content-wrapper>ol:not([cdkVirtualFor]),.cdk-virtual-scroll-orientation-horizontal .cdk-virtual-scroll-content-wrapper>table:not([cdkVirtualFor]),.cdk-virtual-scroll-orientation-horizontal .cdk-virtual-scroll-content-wrapper>ul:not([cdkVirtualFor]){padding-left:0;padding-right:0;margin-left:0;margin-right:0;border-left-width:0;border-right-width:0;outline:0}.cdk-virtual-scroll-orientation-vertical .cdk-virtual-scroll-content-wrapper{min-width:100%}.cdk-virtual-scroll-orientation-vertical .cdk-virtual-scroll-content-wrapper>dl:not([cdkVirtualFor]),.cdk-virtual-scroll-orientation-vertical .cdk-virtual-scroll-content-wrapper>ol:not([cdkVirtualFor]),.cdk-virtual-scroll-orientation-vertical .cdk-virtual-scroll-content-wrapper>table:not([cdkVirtualFor]),.cdk-virtual-scroll-orientation-vertical .cdk-virtual-scroll-content-wrapper>ul:not([cdkVirtualFor]){padding-top:0;padding-bottom:0;margin-top:0;margin-bottom:0;border-top-width:0;border-bottom-width:0;outline:0}.cdk-virtual-scroll-spacer{position:absolute;top:0;left:0;height:1px;width:1px;transform-origin:0 0}[dir=rtl] .cdk-virtual-scroll-spacer{right:0;left:auto;transform-origin:100% 0}"],
- host: {
- 'class': 'cdk-virtual-scroll-viewport',
- '[class.cdk-virtual-scroll-orientation-horizontal]': 'orientation === "horizontal"',
- '[class.cdk-virtual-scroll-orientation-vertical]': 'orientation !== "horizontal"',
- },
- encapsulation: ViewEncapsulation.None,
- changeDetection: ChangeDetectionStrategy.OnPush,
- providers: [{
- provide: CdkScrollable,
- useExisting: CdkVirtualScrollViewport,
- }]
- },] },
- ];
- /** @nocollapse */
- CdkVirtualScrollViewport.ctorParameters = function () { return [
- { type: ElementRef },
- { type: ChangeDetectorRef },
- { type: NgZone },
- { type: undefined, decorators: [{ type: Optional }, { type: Inject, args: [VIRTUAL_SCROLL_STRATEGY,] }] },
- { type: Directionality, decorators: [{ type: Optional }] },
- { type: ScrollDispatcher }
- ]; };
- CdkVirtualScrollViewport.propDecorators = {
- orientation: [{ type: Input }],
- scrolledIndexChange: [{ type: Output }],
- _contentWrapper: [{ type: ViewChild, args: ['contentWrapper', { static: true },] }]
- };
- return CdkVirtualScrollViewport;
- }(CdkScrollable));
- /**
- * @fileoverview added by tsickle
- * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
- */
- /**
- * Helper to extract size from a DOM Node.
- * @param {?} orientation
- * @param {?} node
- * @return {?}
- */
- function getSize(orientation, node) {
- /** @type {?} */
- var el = (/** @type {?} */ (node));
- if (!el.getBoundingClientRect) {
- return 0;
- }
- /** @type {?} */
- var rect = el.getBoundingClientRect();
- return orientation == 'horizontal' ? rect.width : rect.height;
- }
- /**
- * A directive similar to `ngForOf` to be used for rendering data inside a virtual scrolling
- * container.
- * @template T
- */
- var CdkVirtualForOf = /** @class */ (function () {
- function CdkVirtualForOf(_viewContainerRef, _template, _differs, _viewport, ngZone) {
- var _this = this;
- this._viewContainerRef = _viewContainerRef;
- this._template = _template;
- this._differs = _differs;
- this._viewport = _viewport;
- /**
- * Emits when the rendered view of the data changes.
- */
- this.viewChange = new Subject();
- /**
- * Subject that emits when a new DataSource instance is given.
- */
- this._dataSourceChanges = new Subject();
- /**
- * The size of the cache used to store templates that are not being used for re-use later.
- * Setting the cache size to `0` will disable caching. Defaults to 20 templates.
- */
- this.cdkVirtualForTemplateCacheSize = 20;
- /**
- * Emits whenever the data in the current DataSource changes.
- */
- this.dataStream = this._dataSourceChanges
- .pipe(
- // Start off with null `DataSource`.
- startWith((/** @type {?} */ (null))),
- // Bundle up the previous and current data sources so we can work with both.
- pairwise(),
- // Use `_changeDataSource` to disconnect from the previous data source and connect to the
- // new one, passing back a stream of data changes which we run through `switchMap` to give
- // us a data stream that emits the latest data from whatever the current `DataSource` is.
- switchMap((/**
- * @param {?} __0
- * @return {?}
- */
- function (_a) {
- var prev = _a[0], cur = _a[1];
- return _this._changeDataSource(prev, cur);
- })),
- // Replay the last emitted data when someone subscribes.
- shareReplay(1));
- /**
- * The differ used to calculate changes to the data.
- */
- this._differ = null;
- /**
- * The template cache used to hold on ot template instancess that have been stamped out, but don't
- * currently need to be rendered. These instances will be reused in the future rather than
- * stamping out brand new ones.
- */
- this._templateCache = [];
- /**
- * Whether the rendered data should be updated during the next ngDoCheck cycle.
- */
- this._needsUpdate = false;
- this._destroyed = new Subject();
- this.dataStream.subscribe((/**
- * @param {?} data
- * @return {?}
- */
- function (data) {
- _this._data = data;
- _this._onRenderedDataChange();
- }));
- this._viewport.renderedRangeStream.pipe(takeUntil(this._destroyed)).subscribe((/**
- * @param {?} range
- * @return {?}
- */
- function (range) {
- _this._renderedRange = range;
- ngZone.run((/**
- * @return {?}
- */
- function () { return _this.viewChange.next(_this._renderedRange); }));
- _this._onRenderedDataChange();
- }));
- this._viewport.attach(this);
- }
- Object.defineProperty(CdkVirtualForOf.prototype, "cdkVirtualForOf", {
- /** The DataSource to display. */
- get: /**
- * The DataSource to display.
- * @return {?}
- */
- function () {
- return this._cdkVirtualForOf;
- },
- set: /**
- * @param {?} value
- * @return {?}
- */
- function (value) {
- this._cdkVirtualForOf = value;
- /** @type {?} */
- var ds = isDataSource(value) ? value :
- // Slice the value if its an NgIterable to ensure we're working with an array.
- new ArrayDataSource(value instanceof Observable ? value : Array.prototype.slice.call(value || []));
- this._dataSourceChanges.next(ds);
- },
- enumerable: true,
- configurable: true
- });
- Object.defineProperty(CdkVirtualForOf.prototype, "cdkVirtualForTrackBy", {
- /**
- * The `TrackByFunction` to use for tracking changes. The `TrackByFunction` takes the index and
- * the item and produces a value to be used as the item's identity when tracking changes.
- */
- get: /**
- * The `TrackByFunction` to use for tracking changes. The `TrackByFunction` takes the index and
- * the item and produces a value to be used as the item's identity when tracking changes.
- * @return {?}
- */
- function () {
- return this._cdkVirtualForTrackBy;
- },
- set: /**
- * @param {?} fn
- * @return {?}
- */
- function (fn) {
- var _this = this;
- this._needsUpdate = true;
- this._cdkVirtualForTrackBy = fn ?
- (/**
- * @param {?} index
- * @param {?} item
- * @return {?}
- */
- function (index, item) { return fn(index + (_this._renderedRange ? _this._renderedRange.start : 0), item); }) :
- undefined;
- },
- enumerable: true,
- configurable: true
- });
- Object.defineProperty(CdkVirtualForOf.prototype, "cdkVirtualForTemplate", {
- /** The template used to stamp out new elements. */
- set: /**
- * The template used to stamp out new elements.
- * @param {?} value
- * @return {?}
- */
- function (value) {
- if (value) {
- this._needsUpdate = true;
- this._template = value;
- }
- },
- enumerable: true,
- configurable: true
- });
- /**
- * Measures the combined size (width for horizontal orientation, height for vertical) of all items
- * in the specified range. Throws an error if the range includes items that are not currently
- * rendered.
- */
- /**
- * Measures the combined size (width for horizontal orientation, height for vertical) of all items
- * in the specified range. Throws an error if the range includes items that are not currently
- * rendered.
- * @param {?} range
- * @param {?} orientation
- * @return {?}
- */
- CdkVirtualForOf.prototype.measureRangeSize = /**
- * Measures the combined size (width for horizontal orientation, height for vertical) of all items
- * in the specified range. Throws an error if the range includes items that are not currently
- * rendered.
- * @param {?} range
- * @param {?} orientation
- * @return {?}
- */
- function (range, orientation) {
- if (range.start >= range.end) {
- return 0;
- }
- if (range.start < this._renderedRange.start || range.end > this._renderedRange.end) {
- throw Error("Error: attempted to measure an item that isn't rendered.");
- }
- // The index into the list of rendered views for the first item in the range.
- /** @type {?} */
- var renderedStartIndex = range.start - this._renderedRange.start;
- // The length of the range we're measuring.
- /** @type {?} */
- var rangeLen = range.end - range.start;
- // Loop over all root nodes for all items in the range and sum up their size.
- /** @type {?} */
- var totalSize = 0;
- /** @type {?} */
- var i = rangeLen;
- while (i--) {
- /** @type {?} */
- var view = (/** @type {?} */ (this._viewContainerRef.get(i + renderedStartIndex)));
- /** @type {?} */
- var j = view ? view.rootNodes.length : 0;
- while (j--) {
- totalSize += getSize(orientation, (/** @type {?} */ (view)).rootNodes[j]);
- }
- }
- return totalSize;
- };
- /**
- * @return {?}
- */
- CdkVirtualForOf.prototype.ngDoCheck = /**
- * @return {?}
- */
- function () {
- if (this._differ && this._needsUpdate) {
- // TODO(mmalerba): We should differentiate needs update due to scrolling and a new portion of
- // this list being rendered (can use simpler algorithm) vs needs update due to data actually
- // changing (need to do this diff).
- /** @type {?} */
- var changes = this._differ.diff(this._renderedItems);
- if (!changes) {
- this._updateContext();
- }
- else {
- this._applyChanges(changes);
- }
- this._needsUpdate = false;
- }
- };
- /**
- * @return {?}
- */
- CdkVirtualForOf.prototype.ngOnDestroy = /**
- * @return {?}
- */
- function () {
- this._viewport.detach();
- this._dataSourceChanges.next();
- this._dataSourceChanges.complete();
- this.viewChange.complete();
- this._destroyed.next();
- this._destroyed.complete();
- for (var _i = 0, _a = this._templateCache; _i < _a.length; _i++) {
- var view = _a[_i];
- view.destroy();
- }
- };
- /** React to scroll state changes in the viewport. */
- /**
- * React to scroll state changes in the viewport.
- * @private
- * @return {?}
- */
- CdkVirtualForOf.prototype._onRenderedDataChange = /**
- * React to scroll state changes in the viewport.
- * @private
- * @return {?}
- */
- function () {
- if (!this._renderedRange) {
- return;
- }
- this._renderedItems = this._data.slice(this._renderedRange.start, this._renderedRange.end);
- if (!this._differ) {
- this._differ = this._differs.find(this._renderedItems).create(this.cdkVirtualForTrackBy);
- }
- this._needsUpdate = true;
- };
- /** Swap out one `DataSource` for another. */
- /**
- * Swap out one `DataSource` for another.
- * @private
- * @param {?} oldDs
- * @param {?} newDs
- * @return {?}
- */
- CdkVirtualForOf.prototype._changeDataSource = /**
- * Swap out one `DataSource` for another.
- * @private
- * @param {?} oldDs
- * @param {?} newDs
- * @return {?}
- */
- function (oldDs, newDs) {
- if (oldDs) {
- oldDs.disconnect(this);
- }
- this._needsUpdate = true;
- return newDs ? newDs.connect(this) : of();
- };
- /** Update the `CdkVirtualForOfContext` for all views. */
- /**
- * Update the `CdkVirtualForOfContext` for all views.
- * @private
- * @return {?}
- */
- CdkVirtualForOf.prototype._updateContext = /**
- * Update the `CdkVirtualForOfContext` for all views.
- * @private
- * @return {?}
- */
- function () {
- /** @type {?} */
- var count = this._data.length;
- /** @type {?} */
- var i = this._viewContainerRef.length;
- while (i--) {
- /** @type {?} */
- var view = (/** @type {?} */ (this._viewContainerRef.get(i)));
- view.context.index = this._renderedRange.start + i;
- view.context.count = count;
- this._updateComputedContextProperties(view.context);
- view.detectChanges();
- }
- };
- /** Apply changes to the DOM. */
- /**
- * Apply changes to the DOM.
- * @private
- * @param {?} changes
- * @return {?}
- */
- CdkVirtualForOf.prototype._applyChanges = /**
- * Apply changes to the DOM.
- * @private
- * @param {?} changes
- * @return {?}
- */
- function (changes) {
- var _this = this;
- // Rearrange the views to put them in the right location.
- changes.forEachOperation((/**
- * @param {?} record
- * @param {?} adjustedPreviousIndex
- * @param {?} currentIndex
- * @return {?}
- */
- function (record, adjustedPreviousIndex, currentIndex) {
- if (record.previousIndex == null) { // Item added.
- // Item added.
- /** @type {?} */
- var view = _this._insertViewForNewItem((/** @type {?} */ (currentIndex)));
- view.context.$implicit = record.item;
- }
- else if (currentIndex == null) { // Item removed.
- _this._cacheView(_this._detachView((/** @type {?} */ (adjustedPreviousIndex))));
- }
- else { // Item moved.
- // Item moved.
- /** @type {?} */
- var view = (/** @type {?} */ (_this._viewContainerRef.get((/** @type {?} */ (adjustedPreviousIndex)))));
- _this._viewContainerRef.move(view, currentIndex);
- view.context.$implicit = record.item;
- }
- }));
- // Update $implicit for any items that had an identity change.
- changes.forEachIdentityChange((/**
- * @param {?} record
- * @return {?}
- */
- function (record) {
- /** @type {?} */
- var view = (/** @type {?} */ (_this._viewContainerRef.get((/** @type {?} */ (record.currentIndex)))));
- view.context.$implicit = record.item;
- }));
- // Update the context variables on all items.
- /** @type {?} */
- var count = this._data.length;
- /** @type {?} */
- var i = this._viewContainerRef.length;
- while (i--) {
- /** @type {?} */
- var view = (/** @type {?} */ (this._viewContainerRef.get(i)));
- view.context.index = this._renderedRange.start + i;
- view.context.count = count;
- this._updateComputedContextProperties(view.context);
- }
- };
- /** Cache the given detached view. */
- /**
- * Cache the given detached view.
- * @private
- * @param {?} view
- * @return {?}
- */
- CdkVirtualForOf.prototype._cacheView = /**
- * Cache the given detached view.
- * @private
- * @param {?} view
- * @return {?}
- */
- function (view) {
- if (this._templateCache.length < this.cdkVirtualForTemplateCacheSize) {
- this._templateCache.push(view);
- }
- else {
- /** @type {?} */
- var index = this._viewContainerRef.indexOf(view);
- // It's very unlikely that the index will ever be -1, but just in case,
- // destroy the view on its own, otherwise destroy it through the
- // container to ensure that all the references are removed.
- if (index === -1) {
- view.destroy();
- }
- else {
- this._viewContainerRef.remove(index);
- }
- }
- };
- /** Inserts a view for a new item, either from the cache or by creating a new one. */
- /**
- * Inserts a view for a new item, either from the cache or by creating a new one.
- * @private
- * @param {?} index
- * @return {?}
- */
- CdkVirtualForOf.prototype._insertViewForNewItem = /**
- * Inserts a view for a new item, either from the cache or by creating a new one.
- * @private
- * @param {?} index
- * @return {?}
- */
- function (index) {
- return this._insertViewFromCache(index) || this._createEmbeddedViewAt(index);
- };
- /** Update the computed properties on the `CdkVirtualForOfContext`. */
- /**
- * Update the computed properties on the `CdkVirtualForOfContext`.
- * @private
- * @param {?} context
- * @return {?}
- */
- CdkVirtualForOf.prototype._updateComputedContextProperties = /**
- * Update the computed properties on the `CdkVirtualForOfContext`.
- * @private
- * @param {?} context
- * @return {?}
- */
- function (context) {
- context.first = context.index === 0;
- context.last = context.index === context.count - 1;
- context.even = context.index % 2 === 0;
- context.odd = !context.even;
- };
- /** Creates a new embedded view and moves it to the given index */
- /**
- * Creates a new embedded view and moves it to the given index
- * @private
- * @param {?} index
- * @return {?}
- */
- CdkVirtualForOf.prototype._createEmbeddedViewAt = /**
- * Creates a new embedded view and moves it to the given index
- * @private
- * @param {?} index
- * @return {?}
- */
- function (index) {
- // Note that it's important that we insert the item directly at the proper index,
- // rather than inserting it and the moving it in place, because if there's a directive
- // on the same node that injects the `ViewContainerRef`, Angular will insert another
- // comment node which can throw off the move when it's being repeated for all items.
- return this._viewContainerRef.createEmbeddedView(this._template, {
- $implicit: (/** @type {?} */ (null)),
- cdkVirtualForOf: this._cdkVirtualForOf,
- index: -1,
- count: -1,
- first: false,
- last: false,
- odd: false,
- even: false
- }, index);
- };
- /** Inserts a recycled view from the cache at the given index. */
- /**
- * Inserts a recycled view from the cache at the given index.
- * @private
- * @param {?} index
- * @return {?}
- */
- CdkVirtualForOf.prototype._insertViewFromCache = /**
- * Inserts a recycled view from the cache at the given index.
- * @private
- * @param {?} index
- * @return {?}
- */
- function (index) {
- /** @type {?} */
- var cachedView = this._templateCache.pop();
- if (cachedView) {
- this._viewContainerRef.insert(cachedView, index);
- }
- return cachedView || null;
- };
- /** Detaches the embedded view at the given index. */
- /**
- * Detaches the embedded view at the given index.
- * @private
- * @param {?} index
- * @return {?}
- */
- CdkVirtualForOf.prototype._detachView = /**
- * Detaches the embedded view at the given index.
- * @private
- * @param {?} index
- * @return {?}
- */
- function (index) {
- return (/** @type {?} */ (this._viewContainerRef.detach(index)));
- };
- CdkVirtualForOf.decorators = [
- { type: Directive, args: [{
- selector: '[cdkVirtualFor][cdkVirtualForOf]',
- },] },
- ];
- /** @nocollapse */
- CdkVirtualForOf.ctorParameters = function () { return [
- { type: ViewContainerRef },
- { type: TemplateRef },
- { type: IterableDiffers },
- { type: CdkVirtualScrollViewport, decorators: [{ type: SkipSelf }] },
- { type: NgZone }
- ]; };
- CdkVirtualForOf.propDecorators = {
- cdkVirtualForOf: [{ type: Input }],
- cdkVirtualForTrackBy: [{ type: Input }],
- cdkVirtualForTemplate: [{ type: Input }],
- cdkVirtualForTemplateCacheSize: [{ type: Input }]
- };
- return CdkVirtualForOf;
- }());
- /**
- * @fileoverview added by tsickle
- * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
- */
- var ScrollingModule = /** @class */ (function () {
- function ScrollingModule() {
- }
- ScrollingModule.decorators = [
- { type: NgModule, args: [{
- imports: [BidiModule, PlatformModule],
- exports: [
- BidiModule,
- CdkFixedSizeVirtualScroll,
- CdkScrollable,
- CdkVirtualForOf,
- CdkVirtualScrollViewport,
- ],
- declarations: [
- CdkFixedSizeVirtualScroll,
- CdkScrollable,
- CdkVirtualForOf,
- CdkVirtualScrollViewport,
- ],
- },] },
- ];
- return ScrollingModule;
- }());
- /**
- * @deprecated ScrollDispatchModule has been renamed to ScrollingModule.
- * \@breaking-change 8.0.0 delete this alias
- */
- var ScrollDispatchModule = /** @class */ (function () {
- function ScrollDispatchModule() {
- }
- ScrollDispatchModule.decorators = [
- { type: NgModule, args: [{
- imports: [ScrollingModule],
- exports: [ScrollingModule],
- },] },
- ];
- return ScrollDispatchModule;
- }());
- /**
- * @fileoverview added by tsickle
- * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
- */
- /**
- * Time in ms to throttle the resize events by default.
- * @type {?}
- */
- var DEFAULT_RESIZE_TIME = 20;
- /**
- * Simple utility for getting the bounds of the browser viewport.
- * \@docs-private
- */
- var ViewportRuler = /** @class */ (function () {
- function ViewportRuler(_platform, ngZone) {
- var _this = this;
- this._platform = _platform;
- ngZone.runOutsideAngular((/**
- * @return {?}
- */
- function () {
- _this._change = _platform.isBrowser ?
- merge(fromEvent(window, 'resize'), fromEvent(window, 'orientationchange')) :
- of();
- // Note that we need to do the subscription inside `runOutsideAngular`
- // since subscribing is what causes the event listener to be added.
- _this._invalidateCache = _this.change().subscribe((/**
- * @return {?}
- */
- function () { return _this._updateViewportSize(); }));
- }));
- }
- /**
- * @return {?}
- */
- ViewportRuler.prototype.ngOnDestroy = /**
- * @return {?}
- */
- function () {
- this._invalidateCache.unsubscribe();
- };
- /** Returns the viewport's width and height. */
- /**
- * Returns the viewport's width and height.
- * @return {?}
- */
- ViewportRuler.prototype.getViewportSize = /**
- * Returns the viewport's width and height.
- * @return {?}
- */
- function () {
- if (!this._viewportSize) {
- this._updateViewportSize();
- }
- /** @type {?} */
- var output = { width: this._viewportSize.width, height: this._viewportSize.height };
- // If we're not on a browser, don't cache the size since it'll be mocked out anyway.
- if (!this._platform.isBrowser) {
- this._viewportSize = (/** @type {?} */ (null));
- }
- return output;
- };
- /** Gets a ClientRect for the viewport's bounds. */
- /**
- * Gets a ClientRect for the viewport's bounds.
- * @return {?}
- */
- ViewportRuler.prototype.getViewportRect = /**
- * Gets a ClientRect for the viewport's bounds.
- * @return {?}
- */
- function () {
- // Use the document element's bounding rect rather than the window scroll properties
- // (e.g. pageYOffset, scrollY) due to in issue in Chrome and IE where window scroll
- // properties and client coordinates (boundingClientRect, clientX/Y, etc.) are in different
- // conceptual viewports. Under most circumstances these viewports are equivalent, but they
- // can disagree when the page is pinch-zoomed (on devices that support touch).
- // See https://bugs.chromium.org/p/chromium/issues/detail?id=489206#c4
- // We use the documentElement instead of the body because, by default (without a css reset)
- // browsers typically give the document body an 8px margin, which is not included in
- // getBoundingClientRect().
- /** @type {?} */
- var scrollPosition = this.getViewportScrollPosition();
- var _a = this.getViewportSize(), width = _a.width, height = _a.height;
- return {
- top: scrollPosition.top,
- left: scrollPosition.left,
- bottom: scrollPosition.top + height,
- right: scrollPosition.left + width,
- height: height,
- width: width,
- };
- };
- /** Gets the (top, left) scroll position of the viewport. */
- /**
- * Gets the (top, left) scroll position of the viewport.
- * @return {?}
- */
- ViewportRuler.prototype.getViewportScrollPosition = /**
- * Gets the (top, left) scroll position of the viewport.
- * @return {?}
- */
- function () {
- // While we can get a reference to the fake document
- // during SSR, it doesn't have getBoundingClientRect.
- if (!this._platform.isBrowser) {
- return { top: 0, left: 0 };
- }
- // The top-left-corner of the viewport is determined by the scroll position of the document
- // body, normally just (scrollLeft, scrollTop). However, Chrome and Firefox disagree about
- // whether `document.body` or `document.documentElement` is the scrolled element, so reading
- // `scrollTop` and `scrollLeft` is inconsistent. However, using the bounding rect of
- // `document.documentElement` works consistently, where the `top` and `left` values will
- // equal negative the scroll position.
- /** @type {?} */
- var documentElement = (/** @type {?} */ (document.documentElement));
- /** @type {?} */
- var documentRect = documentElement.getBoundingClientRect();
- /** @type {?} */
- var top = -documentRect.top || document.body.scrollTop || window.scrollY ||
- documentElement.scrollTop || 0;
- /** @type {?} */
- var left = -documentRect.left || document.body.scrollLeft || window.scrollX ||
- documentElement.scrollLeft || 0;
- return { top: top, left: left };
- };
- /**
- * Returns a stream that emits whenever the size of the viewport changes.
- * @param throttleTime Time in milliseconds to throttle the stream.
- */
- /**
- * Returns a stream that emits whenever the size of the viewport changes.
- * @param {?=} throttleTime Time in milliseconds to throttle the stream.
- * @return {?}
- */
- ViewportRuler.prototype.change = /**
- * Returns a stream that emits whenever the size of the viewport changes.
- * @param {?=} throttleTime Time in milliseconds to throttle the stream.
- * @return {?}
- */
- function (throttleTime) {
- if (throttleTime === void 0) { throttleTime = DEFAULT_RESIZE_TIME; }
- return throttleTime > 0 ? this._change.pipe(auditTime(throttleTime)) : this._change;
- };
- /** Updates the cached viewport size. */
- /**
- * Updates the cached viewport size.
- * @private
- * @return {?}
- */
- ViewportRuler.prototype._updateViewportSize = /**
- * Updates the cached viewport size.
- * @private
- * @return {?}
- */
- function () {
- this._viewportSize = this._platform.isBrowser ?
- { width: window.innerWidth, height: window.innerHeight } :
- { width: 0, height: 0 };
- };
- ViewportRuler.decorators = [
- { type: Injectable, args: [{ providedIn: 'root' },] },
- ];
- /** @nocollapse */
- ViewportRuler.ctorParameters = function () { return [
- { type: Platform },
- { type: NgZone }
- ]; };
- /** @nocollapse */ ViewportRuler.ngInjectableDef = ɵɵdefineInjectable({ factory: function ViewportRuler_Factory() { return new ViewportRuler(ɵɵinject(Platform), ɵɵinject(NgZone)); }, token: ViewportRuler, providedIn: "root" });
- return ViewportRuler;
- }());
- /**
- * \@docs-private \@deprecated \@breaking-change 8.0.0
- * @param {?} parentRuler
- * @param {?} platform
- * @param {?} ngZone
- * @return {?}
- */
- function VIEWPORT_RULER_PROVIDER_FACTORY(parentRuler, platform, ngZone) {
- return parentRuler || new ViewportRuler(platform, ngZone);
- }
- /**
- * \@docs-private \@deprecated \@breaking-change 8.0.0
- * @type {?}
- */
- var VIEWPORT_RULER_PROVIDER = {
- // If there is already a ViewportRuler available, use that. Otherwise, provide a new one.
- provide: ViewportRuler,
- deps: [[new Optional(), new SkipSelf(), ViewportRuler], Platform, NgZone],
- useFactory: VIEWPORT_RULER_PROVIDER_FACTORY
- };
- /**
- * @fileoverview added by tsickle
- * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
- */
- /**
- * @fileoverview added by tsickle
- * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
- */
- export { _fixedSizeVirtualScrollStrategyFactory, FixedSizeVirtualScrollStrategy, CdkFixedSizeVirtualScroll, SCROLL_DISPATCHER_PROVIDER_FACTORY, DEFAULT_SCROLL_TIME, ScrollDispatcher, SCROLL_DISPATCHER_PROVIDER, CdkScrollable, ScrollingModule, ScrollDispatchModule, VIEWPORT_RULER_PROVIDER_FACTORY, DEFAULT_RESIZE_TIME, ViewportRuler, VIEWPORT_RULER_PROVIDER, CdkVirtualForOf, VIRTUAL_SCROLL_STRATEGY, CdkVirtualScrollViewport };
- //# sourceMappingURL=scrolling.es5.js.map
|