import { Directive , EventEmitter , Inject , Input , OnChanges , OnDestroy , Optional , Output , SimpleChanges } from '@angular/core' ; import { NavigationCancel , NavigationEnd , NavigationError , Router , UrlTree } from '@angular/router' ; import { DOCUMENT } from '@angular/common' ; import { EasingLogic , PageScrollInstance , PageScrollOptions , PageScrollService } from 'ngx-page-scroll-core' ; import { filter , take } from 'rxjs/operators' ; @ Directive ( { selector : '[pageScroll]' , host : { '(click)' : 'handleClick($event)' , } , } ) export class NgxPageScrollDirective implements OnChanges , OnDestroy { @ Input ( ) public routerLink : any ; @ Input ( ) public href : string ; @ Input ( ) public fragment : string ; @ Input ( ) public pageScrollTarget : string ; @ Input ( ) public pageScrollHorizontal : boolean ; @ Input ( ) public pageScrollOffset : number ; @ Input ( ) public pageScrollDuration : number ; @ Input ( ) public pageScrollSpeed : number ; @ Input ( ) public pageScrollEasing : EasingLogic ; @ Input ( ) public pageScrollInterruptible : boolean ; @ Input ( ) public pageScrollInView : boolean ; @ Input ( ) public pageScrollAdjustHash = false ; @ Input ( ) public pageScroll : string ; @ Output ( ) pageScrollFinish : EventEmitter < boolean > = new EventEmitter < boolean > ( ) ; private pageScrollInstance : PageScrollInstance ; private document : Document ; constructor ( private pageScrollService , @ Optional ( ) private router , @ Inject ( DOCUMENT ) document ) { this . document = ( document as Document ) ; } ngOnChanges ( changes ) { this . pageScrollInstance = undefined ; } ngOnDestroy ( ) { if ( this . pageScrollInstance ) { this . pageScrollService . stop ( this . pageScrollInstance ) ; } } private getPageScrollTarget ( ) { return this . pageScrollTarget || this . href || ( this . fragment ? '#' + this . fragment : '' ) ; } private generatePageScrollInstance ( ) { if ( this . pageScrollInstance === undefined || this . pageScrollInstance === null ) { const options = { document : this . document , scrollTarget : this . getPageScrollTarget ( ) , } ; if ( this . pageScroll ) { options . namespace = this . pageScroll ; } if ( this . pageScrollHorizontal !== undefined && this . pageScrollHorizontal !== null ) { options . verticalScrolling = ! this . pageScrollHorizontal ; } if ( this . pageScrollOffset !== undefined && this . pageScrollOffset !== null ) { options . scrollOffset = this . pageScrollOffset ; } if ( this . pageScrollInterruptible !== undefined && this . pageScrollInterruptible !== null ) { options . interruptible = this . pageScrollInterruptible ; } if ( this . pageScrollInView !== undefined && this . pageScrollInView !== null ) { options . scrollInView = this . pageScrollInView ; } if ( this . pageScrollEasing ) { options . easingLogic = this . pageScrollEasing ; } if ( this . pageScrollDuration !== undefined && this . pageScrollDuration !== null ) { options . duration = this . pageScrollDuration ; } if ( this . pageScrollSpeed !== undefined && this . pageScrollSpeed !== null ) { options . speed = this . pageScrollSpeed ; } if ( this . pageScrollFinish ) { options . scrollFinishListener = this . pageScrollFinish ; } this . pageScrollInstance = this . pageScrollService . create ( options ) ; } return this . pageScrollInstance ; } private pushRouterState ( ) { if ( this . pageScrollAdjustHash && typeof this . pageScrollInstance . pageScrollOptions . scrollTarget === 'string' && ( this . pageScrollInstance . pageScrollOptions . scrollTarget as string ) . substr ( 0 , 1 ) === '#' ) { this . router . navigate ( [ ] , { fragment : ( this . pageScrollInstance . pageScrollOptions . scrollTarget as string ) . substr ( 1 ) , queryParamsHandling : 'preserve' , } ) ; } } private scroll ( ) { const pageScrollInstance = this . generatePageScrollInstance ( ) ; this . pushRouterState ( ) ; this . pageScrollService . start ( pageScrollInstance ) ; } public handleClick ( clickEvent ) { if ( this . routerLink && this . router !== null && this . router !== undefined ) { let urlTree ; if ( typeof this . routerLink === 'string' ) { urlTree = this . router . parseUrl ( this . routerLink ) ; } else { urlTree = this . router . createUrlTree ( this . routerLink ) ; } if ( ! this . router . isActive ( urlTree , true ) ) { this . router . events . pipe ( filter ( routerEvent => { return routerEvent instanceof NavigationEnd || routerEvent instanceof NavigationError || routerEvent instanceof NavigationCancel ; } ) , take ( 1 ) ) . subscribe ( ( routerEvent ) => { if ( routerEvent instanceof NavigationEnd ) { setTimeout ( ( ) => { this . scroll ( ) ; } , 0 ) ; } } ) ; return false ; } } this . scroll ( ) ; return false ; } }