first-npm-package-nicule
Version:
This isi first npm package
117 lines (100 loc) • 3.62 kB
text/typescript
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';
export class LinkDirective implements OnDestroy, OnInit {
beforeNavigation = new EventEmitter<'external' | 'local'>();
target = '_blank';
delayBeforeNavigation = 0;
queryParams = {};
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;
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();
}
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);
}
}
}
}