UNPKG

first-npm-package-nicule

Version:

This isi first npm package

117 lines (100 loc) 3.62 kB
import {debounceTime} from 'rxjs/operators'; import { Directive, ElementRef, EventEmitter, HostBinding, HostListener, Input, OnDestroy, OnInit, Output } from '@angular/core'; import { HypermediaLink } from './../interfaces'; import { ActivatedRoute, Router } from '@angular/router'; import { Subscription } from 'rxjs'; import { HrefFormatterProvider } from '../services/href-formatter-provider.service'; @Directive({ selector: '[hmLink]' }) export class LinkDirective implements OnDestroy, OnInit { @Output() beforeNavigation = new EventEmitter<'external' | 'local'>(); @Input() target = '_blank'; @Input() delayBeforeNavigation = 0; @Input() queryParams = {}; @Input() set hmLink(link: HypermediaLink) { if (!link) { return; } this.isPage = link.rel.includes('page'); this.isExternal = link.rel.includes('external'); if (this.isPage) { const hrefFormatter = this.scopeProvider .getHrefFormatters() .find(scope => scope.matchesLink(link)); this.href = hrefFormatter.makePathFromHref(link.href); } else if (this.isExternal) { this.href = link.href; } } isPage = false; isExternal = false; href: string; @HostBinding('class.active-link') activeClass: boolean; fragmentSubscription: Subscription; constructor(private router: Router, private activatedRoute: ActivatedRoute, private scopeProvider: HrefFormatterProvider) { this.fragmentSubscription = router.events.pipe(debounceTime(100)) .subscribe(() => { if (this.href) { this.activeClass = router.isActive(this.href, true); } }); } ngOnInit(): void { this.activeClass = this.router.isActive(this.href, true); } private scrollToTop(): void { const element = document.querySelector('html'); if (element) { setTimeout(() => { element.scrollIntoView({ behavior: 'smooth', block: 'start', inline: 'nearest' }); }, 100); } } ngOnDestroy(): void { this.fragmentSubscription.unsubscribe(); } @HostListener('click') onClick(): void { if (!this.href) { throw new Error('No link was provided!'); } if (this.isPage) { this.beforeNavigation.emit('local'); if(this.delayBeforeNavigation > 0) { setTimeout( () => { this.router.navigateByUrl(this.href, {queryParams: this.queryParams}); }, this.delayBeforeNavigation); } else { this.router.navigateByUrl(this.href, {queryParams: this.queryParams}); } this.scrollToTop(); } else if (this.isExternal) { this.beforeNavigation.emit('external'); var esc = encodeURIComponent; var query = Object.keys(this.queryParams) .map(k => esc(k) + '=' + esc(this.queryParams[k])) .join('&'); if(query != '') { query = "?" + query; } if(this.delayBeforeNavigation > 0) { setTimeout( () => { window.open(this.href + query, this.target); }, this.delayBeforeNavigation); } else { window.open(this.href + query, this.target); } } } }