@@ -11,14 +11,22 @@ import {Platform} from '../platform';
1111import { ElementRef , Service , NgZone , OnDestroy , RendererFactory2 , inject } from '@angular/core' ;
1212import { of as observableOf , Subject , Subscription , Observable , Observer } from 'rxjs' ;
1313import { auditTime , filter } from 'rxjs/operators' ;
14- import type { CdkScrollable } from './scrollable' ;
1514
1615/** Time in ms to throttle the scrolling events by default. */
1716export const DEFAULT_SCROLL_TIME = 20 ;
1817
18+ /** Scrollable instance that can be registered with the `ScrollDispatcher`. */
19+ export interface ScrollDispatcherTarget {
20+ /** Observable that emits when the element is scrolled. */
21+ elementScrolled ( ) : Observable < Event > ;
22+
23+ /** Gets the `ElementRef` representing the scrollable element. */
24+ getElementRef ( ) : ElementRef < HTMLElement > ;
25+ }
26+
1927/**
20- * Service contained all registered Scrollable references and emits an event when any one of the
21- * Scrollable references emit a scrolled event.
28+ * Service contained all registered scroll targets and emits
29+ * an event when any one of them emits a scrolled event.
2230 */
2331@Service ( )
2432export class ScrollDispatcher implements OnDestroy {
@@ -27,42 +35,42 @@ export class ScrollDispatcher implements OnDestroy {
2735 private _renderer = inject ( RendererFactory2 ) . createRenderer ( null , null ) ;
2836 private _cleanupGlobalListener : ( ( ) => void ) | undefined ;
2937
30- /** Subject for notifying that a registered scrollable reference element has been scrolled. */
31- private readonly _scrolled = new Subject < CdkScrollable | void > ( ) ;
38+ /** Subject for notifying that a registered element has been scrolled. */
39+ private readonly _scrolled = new Subject < ScrollDispatcherTarget | void > ( ) ;
3240
3341 /** Keeps track of the amount of subscriptions to `scrolled`. Used for cleaning up afterwards. */
3442 private _scrolledCount = 0 ;
3543
3644 /**
37- * Map of all the scrollable references that are registered with the service and their
45+ * Map of all the scrollable targets that are registered with the service and their
3846 * scroll event subscriptions.
3947 */
40- scrollContainers : Map < CdkScrollable , Subscription > = new Map ( ) ;
48+ readonly scrollContainers : Map < ScrollDispatcherTarget , Subscription > = new Map ( ) ;
4149
4250 /**
4351 * Registers a scrollable instance with the service and listens for its scrolled events. When the
4452 * scrollable is scrolled, the service emits the event to its scrolled observable.
45- * @param scrollable Scrollable instance to be registered.
53+ * @param target Scrollable instance to be registered.
4654 */
47- register ( scrollable : CdkScrollable ) : void {
48- if ( ! this . scrollContainers . has ( scrollable ) ) {
55+ register ( target : ScrollDispatcherTarget ) : void {
56+ if ( ! this . scrollContainers . has ( target ) ) {
4957 this . scrollContainers . set (
50- scrollable ,
51- scrollable . elementScrolled ( ) . subscribe ( ( ) => this . _scrolled . next ( scrollable ) ) ,
58+ target ,
59+ target . elementScrolled ( ) . subscribe ( ( ) => this . _scrolled . next ( target ) ) ,
5260 ) ;
5361 }
5462 }
5563
5664 /**
5765 * De-registers a Scrollable reference and unsubscribes from its scroll event observable.
58- * @param scrollable Scrollable instance to be deregistered.
66+ * @param target Scrollable instance to be deregistered.
5967 */
60- deregister ( scrollable : CdkScrollable ) : void {
61- const scrollableReference = this . scrollContainers . get ( scrollable ) ;
68+ deregister ( target : ScrollDispatcherTarget ) : void {
69+ const ref = this . scrollContainers . get ( target ) ;
6270
63- if ( scrollableReference ) {
64- scrollableReference . unsubscribe ( ) ;
65- this . scrollContainers . delete ( scrollable ) ;
71+ if ( ref ) {
72+ ref . unsubscribe ( ) ;
73+ this . scrollContainers . delete ( target ) ;
6674 }
6775 }
6876
@@ -76,12 +84,12 @@ export class ScrollDispatcher implements OnDestroy {
7684 * If you need to update any data bindings as a result of a scroll event, you have
7785 * to run the callback using `NgZone.run`.
7886 */
79- scrolled ( auditTimeInMs : number = DEFAULT_SCROLL_TIME ) : Observable < CdkScrollable | void > {
87+ scrolled ( auditTimeInMs : number = DEFAULT_SCROLL_TIME ) : Observable < ScrollDispatcherTarget | void > {
8088 if ( ! this . _platform . isBrowser ) {
8189 return observableOf < void > ( ) ;
8290 }
8391
84- return new Observable ( ( observer : Observer < CdkScrollable | void > ) => {
92+ return new Observable ( ( observer : Observer < ScrollDispatcherTarget | void > ) => {
8593 if ( ! this . _cleanupGlobalListener ) {
8694 this . _cleanupGlobalListener = this . _ngZone . runOutsideAngular ( ( ) =>
8795 this . _renderer . listen ( 'document' , 'scroll' , ( ) => this . _scrolled . next ( ) ) ,
@@ -125,39 +133,41 @@ export class ScrollDispatcher implements OnDestroy {
125133 ancestorScrolled (
126134 elementOrElementRef : ElementRef | HTMLElement ,
127135 auditTimeInMs ?: number ,
128- ) : Observable < CdkScrollable | void > {
136+ ) : Observable < ScrollDispatcherTarget | void > {
129137 const ancestors = this . getAncestorScrollContainers ( elementOrElementRef ) ;
130138
131139 return this . scrolled ( auditTimeInMs ) . pipe (
132140 filter ( target => ! target || ancestors . indexOf ( target ) > - 1 ) ,
133141 ) ;
134142 }
135143
136- /** Returns all registered Scrollables that contain the provided element. */
137- getAncestorScrollContainers ( elementOrElementRef : ElementRef | HTMLElement ) : CdkScrollable [ ] {
138- const scrollingContainers : CdkScrollable [ ] = [ ] ;
144+ /** Returns all registered containers that contain the provided element. */
145+ getAncestorScrollContainers (
146+ elementOrElementRef : ElementRef | HTMLElement ,
147+ ) : ScrollDispatcherTarget [ ] {
148+ const scrollingContainers : ScrollDispatcherTarget [ ] = [ ] ;
139149
140- this . scrollContainers . forEach ( ( _subscription : Subscription , scrollable : CdkScrollable ) => {
141- if ( this . _scrollableContainsElement ( scrollable , elementOrElementRef ) ) {
142- scrollingContainers . push ( scrollable ) ;
150+ this . scrollContainers . forEach ( ( _ , target : ScrollDispatcherTarget ) => {
151+ if ( this . _targetContainsElement ( target , elementOrElementRef ) ) {
152+ scrollingContainers . push ( target ) ;
143153 }
144154 } ) ;
145155
146156 return scrollingContainers ;
147157 }
148158
149159 /** Returns true if the element is contained within the provided Scrollable. */
150- private _scrollableContainsElement (
151- scrollable : CdkScrollable ,
160+ private _targetContainsElement (
161+ scrollable : ScrollDispatcherTarget ,
152162 elementOrElementRef : ElementRef | HTMLElement ,
153163 ) : boolean {
154164 let element : HTMLElement | null = coerceElement ( elementOrElementRef ) ;
155- let scrollableElement = scrollable . getElementRef ( ) . nativeElement ;
165+ let targetElement = scrollable . getElementRef ( ) . nativeElement ;
156166
157167 // Traverse through the element parents until we reach null, checking if any of the elements
158168 // are the scrollable's element.
159169 do {
160- if ( element == scrollableElement ) {
170+ if ( element == targetElement ) {
161171 return true ;
162172 }
163173 } while ( ( element = element ! . parentElement ) ) ;
0 commit comments