@cisstech/nge
Version:
NG Essentials is a collection of libraries for Angular developers.
135 lines • 19 kB
JavaScript
import { Directive, ElementRef, Input } from '@angular/core';
import { Scroll } from '@angular/router';
import * as i0 from "@angular/core";
import * as i1 from "@angular/router";
import * as i2 from "@angular/common";
export class NgeDocTocDirective {
constructor(router, location, elementRef, activatedRoute) {
this.router = router;
this.location = location;
this.elementRef = elementRef;
this.activatedRoute = activatedRoute;
this.subscriptions = [];
this.observer = new MutationObserver(() => {
this.observer?.disconnect();
this.build();
});
this.anchors = [];
this.subscriptions.push(this.router.events.subscribe((event) => {
if (event instanceof Scroll && event.anchor) {
this.scroll(event.anchor);
}
}));
}
ngOnDestroy() {
this.intersection?.disconnect();
this.subscriptions.forEach((s) => s.unsubscribe());
}
ngOnChanges() {
this.build();
}
build() {
this.clear();
if (!this.component) {
return;
}
const componentNode = this.component.injector.get(ElementRef).nativeElement;
const tocContainer = this.elementRef.nativeElement;
const h2Nodes = Array.from(componentNode.children).filter((node) => {
return node.tagName === 'H2' && node.parentNode?.isSameNode(componentNode);
});
this.detectIntersection();
const ul = document.createElement('ul');
h2Nodes.forEach((h2) => {
const id = this.dashify(h2.textContent || '');
const target = document.createElement('span');
target.id = id;
h2.insertAdjacentElement('afterend', target);
const li = document.createElement('li');
const anchor = document.createElement('a');
anchor.innerHTML = h2.innerHTML;
// .substring(1) will remove the leading / (prevent errors when baseHref is defined in index.html)
anchor.href = this.location.path().substring(1) + '#' + id;
li.appendChild(anchor);
ul.appendChild(li);
h2.setAttribute('data-toc-id', id);
li.setAttribute('data-toc-id', id);
this.anchors.push(li);
this.intersection?.observe(h2);
});
tocContainer.appendChild(ul);
const { fragment } = this.activatedRoute.snapshot;
if (fragment) {
this.scroll(fragment);
}
this.observer.observe(componentNode, {
childList: true,
subtree: true,
});
}
dashify(input) {
return input
.trim()
.replace(/([a-z])([A-Z])/g, '$1-$2')
.replace(/\W/g, (m) => (/[À-ž]/.test(m) ? m : '-'))
.replace(/^-+|-+$/g, '')
.replace(/-{2,}/g, (m) => '-') // Condense multiple consecutive dashes to one.
.toLowerCase();
}
detectIntersection() {
const tocContainer = this.elementRef.nativeElement;
const rect = tocContainer.getBoundingClientRect();
const bottom = -window.innerHeight + rect.y + 200;
this.intersection?.disconnect();
this.intersection = new IntersectionObserver((entries) => {
entries.forEach((entry) => {
if (entry.isIntersecting) {
this.anchors.forEach((anchor) => {
anchor.classList.remove('active');
const a = anchor.getAttribute('data-toc-id');
const b = entry.target.getAttribute('data-toc-id');
if (a === b) {
anchor.classList.add('active');
}
});
}
});
}, {
// A BOX OF 200px STARTING AT THE POSITION OF THE TOC ELEMENT
rootMargin: `0px 0px ${bottom}px 0px`,
});
}
clear() {
const tocContainer = this.elementRef.nativeElement;
tocContainer.innerHTML = '';
this.observer.disconnect();
this.intersection?.disconnect();
this.anchors = [];
}
scroll(query) {
const targetElement = document.querySelector(`h2[data-toc-id="${query}"]`);
if (!targetElement) {
window.scrollTo(0, 0);
}
else if (!this.isInViewport(targetElement)) {
targetElement.scrollIntoView();
}
}
isInViewport(elem) {
const bounding = elem.getBoundingClientRect();
return (bounding.top >= 0 &&
bounding.left >= 0 &&
bounding.bottom <= (window.innerHeight || document.documentElement.clientHeight) &&
bounding.right <= (window.innerWidth || document.documentElement.clientWidth));
}
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.1", ngImport: i0, type: NgeDocTocDirective, deps: [{ token: i1.Router }, { token: i2.Location }, { token: i0.ElementRef }, { token: i1.ActivatedRoute }], target: i0.ɵɵFactoryTarget.Directive }); }
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "18.2.1", type: NgeDocTocDirective, selector: "[ngeDocToc]", inputs: { component: ["ngeDocToc", "component"] }, usesOnChanges: true, ngImport: i0 }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.1", ngImport: i0, type: NgeDocTocDirective, decorators: [{
type: Directive,
args: [{ selector: '[ngeDocToc]' }]
}], ctorParameters: () => [{ type: i1.Router }, { type: i2.Location }, { type: i0.ElementRef }, { type: i1.ActivatedRoute }], propDecorators: { component: [{
type: Input,
args: ['ngeDocToc']
}] } });
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidG9jLmRpcmVjdGl2ZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL25nZS9kb2Mvc3JjL3JlbmRlcmVyL3RvYy5kaXJlY3RpdmUudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQ0EsT0FBTyxFQUFnQixTQUFTLEVBQUUsVUFBVSxFQUFFLEtBQUssRUFBd0IsTUFBTSxlQUFlLENBQUE7QUFDaEcsT0FBTyxFQUEwQixNQUFNLEVBQUUsTUFBTSxpQkFBaUIsQ0FBQTs7OztBQUloRSxNQUFNLE9BQU8sa0JBQWtCO0lBYTdCLFlBQ21CLE1BQWMsRUFDZCxRQUFrQixFQUNsQixVQUFtQyxFQUNuQyxjQUE4QjtRQUg5QixXQUFNLEdBQU4sTUFBTSxDQUFRO1FBQ2QsYUFBUSxHQUFSLFFBQVEsQ0FBVTtRQUNsQixlQUFVLEdBQVYsVUFBVSxDQUF5QjtRQUNuQyxtQkFBYyxHQUFkLGNBQWMsQ0FBZ0I7UUFoQmhDLGtCQUFhLEdBQW1CLEVBQUUsQ0FBQTtRQUNsQyxhQUFRLEdBQUcsSUFBSSxnQkFBZ0IsQ0FBQyxHQUFHLEVBQUU7WUFDcEQsSUFBSSxDQUFDLFFBQVEsRUFBRSxVQUFVLEVBQUUsQ0FBQTtZQUMzQixJQUFJLENBQUMsS0FBSyxFQUFFLENBQUE7UUFDZCxDQUFDLENBQUMsQ0FBQTtRQUdNLFlBQU8sR0FBa0IsRUFBRSxDQUFBO1FBV2pDLElBQUksQ0FBQyxhQUFhLENBQUMsSUFBSSxDQUNyQixJQUFJLENBQUMsTUFBTSxDQUFDLE1BQU0sQ0FBQyxTQUFTLENBQUMsQ0FBQyxLQUFLLEVBQUUsRUFBRTtZQUNyQyxJQUFJLEtBQUssWUFBWSxNQUFNLElBQUksS0FBSyxDQUFDLE1BQU0sRUFBRSxDQUFDO2dCQUM1QyxJQUFJLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxNQUFNLENBQUMsQ0FBQTtZQUMzQixDQUFDO1FBQ0gsQ0FBQyxDQUFDLENBQ0gsQ0FBQTtJQUNILENBQUM7SUFFRCxXQUFXO1FB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QUM1QixNQUFNLFFBQVEsR0FBRyxJQUFJLENBQUMscUJBQXFCLEVBQUUsQ0FBQTtRQUM3QyxPQUFPLENBQ0wsUUFBUSxDQUFDLEdBQUcsSUFBSSxDQUFDO1lBQ2pCLFFBQVEsQ0FBQyxJQUFJLElBQUksQ0FBQztZQUNsQixRQUFRLENBQUMsTUFBTSxJQUFJLENBQUMsTUFBTSxDQUFDLFdBQVcsSUFBSSxRQUFRLENBQUMsZUFBZSxDQUFDLFlBQVksQ0FBQztZQUNoRixRQUFRLENBQUMsS0FBSyxJQUFJLENBQUMsTUFBTSxDQUFDLFVBQVUsSUFBSSxRQUFRLENBQUMsZUFBZSxDQUFDLFdBQVcsQ0FBQyxDQUM5RSxDQUFBO0lBQ0gsQ0FBQzs4R0ExSlUsa0JBQWtCO2tHQUFsQixrQkFBa0I7OzJGQUFsQixrQkFBa0I7a0JBRDlCLFNBQVM7bUJBQUMsRUFBRSxRQUFRLEVBQUUsYUFBYSxFQUFFO3dKQVlwQyxTQUFTO3NCQURSLEtBQUs7dUJBQUMsV0FBVyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IExvY2F0aW9uIH0gZnJvbSAnQGFuZ3VsYXIvY29tbW9uJ1xuaW1wb3J0IHsgQ29tcG9uZW50UmVmLCBEaXJlY3RpdmUsIEVsZW1lbnRSZWYsIElucHV0LCBPbkNoYW5nZXMsIE9uRGVzdHJveSB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnXG5pbXBvcnQgeyBBY3RpdmF0ZWRSb3V0ZSwgUm91dGVyLCBTY3JvbGwgfSBmcm9tICdAYW5ndWxhci9yb3V0ZXInXG5pbXBvcnQgeyBTdWJzY3JpcHRpb24gfSBmcm9tICdyeGpzJ1xuXG5ARGlyZWN0aXZlKHsgc2VsZWN0b3I6ICdbbmdlRG9jVG9jXScgfSlcbmV4cG9ydCBjbGFzcyBOZ2VEb2NUb2NEaXJlY3RpdmUgaW1wbGVtZW50cyBPbkRlc3Ryb3ksIE9uQ2hhbmdlcyB7XG4gIHByaXZhdGUgcmVhZG9ubHkgc3Vic2NyaXB0aW9uczogU3Vic2NyaXB0aW9uW10gPSBbXVxuICBwcml2YXRlIHJlYWRvbmx5IG9ic2VydmVyID0gbmV3IE11dGF0aW9uT2JzZXJ2ZXIoKCkgPT4ge1xuICAgIHRoaXMub2JzZXJ2ZXI/LmRpc2Nvbm5lY3QoKVxuICAgIHRoaXMuYnVpbGQoKVxuICB9KVxuXG4gIHByaXZhdGUgaW50ZXJzZWN0aW9uPzogSW50ZXJzZWN0aW9uT2JzZXJ2ZXJcbiAgcHJpdmF0ZSBhbmNob3JzOiBIVE1MRWxlbWVudFtdID0gW11cblxuICBASW5wdXQoJ25nZURvY1RvYycpXG4gIGNvbXBvbmVudD86IENvbXBvbmVudFJlZjxhbnk+XG5cbiAgY29uc3RydWN0b3IoXG4gICAgcHJpdmF0ZSByZWFkb25seSByb3V0ZXI6IFJvdXRlcixcbiAgICBwcml2YXRlIHJlYWRvbmx5IGxvY2F0aW9uOiBMb2NhdGlvbixcbiAgICBwcml2YXRlIHJlYWRvbmx5IGVsZW1lbnRSZWY6IEVsZW1lbnRSZWY8SFRNTEVsZW1lbnQ+LFxuICAgIHByaXZhdGUgcmVhZG9ubHkgYWN0aXZhdGVkUm91dGU6IEFjdGl2YXRlZFJvdXRlXG4gICkge1xuICAgIHRoaXMuc3Vic2NyaXB0aW9ucy5wdXNoKFxuICAgICAgdGhpcy5yb3V0ZXIuZXZlbnRzLnN1YnNjcmliZSgoZXZlbnQpID0+IHtcbiAgICAgICAgaWYgKGV2ZW50IGluc3RhbmNlb2YgU2Nyb2xsICYmIGV2ZW50LmFuY2hvcikge1xuICAgICAgICAgIHRoaXMuc2Nyb2xsKGV2ZW50LmFuY2hvcilcbiAgICAgICAgfVxuICAgICAgfSlcbiAgICApXG4gIH1cblxuICBuZ09uRGVzdHJveSgpOiB2b2lkIHtcbiAgICB0aGlzLmludGVyc2VjdGlvbj8uZGlzY29ubmVjdCgpXG4gICAgdGhpcy5zdWJzY3JpcHRpb25zLmZvckVhY2goKHMpID0+IHMudW5zdWJzY3JpYmUoKSlcbiAgfVxuXG4gIG5nT25DaGFuZ2VzKCk6IHZvaWQge1xuICAgIHRoaXMuYnVpbGQoKVxuICB9XG5cbiAgcHJpdmF0ZSBidWlsZCgpOiB2b2lkIHtcbiAgICB0aGlzLmNsZWFyKClcblxuICAgIGlmICghdGhpcy5jb21wb25lbnQpIHtcbiAgICAgIHJldHVyblxuICAgIH1cblxuICAgIGNvbnN0IGNvbXBvbmVudE5vZGUgPSB0aGlzLmNvbXBvbmVudC5pbmplY3Rvci5nZXQoRWxlbWVudFJlZikubmF0aXZlRWxlbWVudCBhcyBIVE1MRWxlbWVudFxuXG4gICAgY29uc3QgdG9jQ29udGFpbmVyID0gdGhpcy5lbGVtZW50UmVmLm5hdGl2ZUVsZW1lbnRcblxuICAgIGNvbnN0IGgyTm9kZXMgPSBBcnJheS5mcm9tKGNvbXBvbmVudE5vZGUuY2hpbGRyZW4pLmZpbHRlcigobm9kZSkgPT4ge1xuICAgICAgcmV0dXJuIG5vZGUudGFnTmFtZSA9PT0gJ0gyJyAmJiBub2RlLnBhcmVudE5vZGU/LmlzU2FtZU5vZGUoY29tcG9uZW50Tm9kZSlcbiAgICB9KVxuXG4gICAgdGhpcy5kZXRlY3RJbnRlcnNlY3Rpb24oKVxuXG4gICAgY29uc3QgdWwgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCd1bCcpXG4gICAgaDJOb2Rlcy5mb3JFYWNoKChoMikgPT4ge1xuICAgICAgY29uc3QgaWQgPSB0aGlzLmRhc2hpZnkoaDIudGV4dENvbnRlbnQgfHwgJycpXG4gICAgICBjb25zdCB0YXJnZXQgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdzcGFuJylcbiAgICAgIHRhcmdldC5pZCA9IGlkXG4gICAgICBoMi5pbnNlcnRBZGphY2VudEVsZW1lbnQoJ2FmdGVyZW5kJywgdGFyZ2V0KVxuXG4gICAgICBjb25zdCBsaSA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2xpJylcbiAgICAgIGNvbnN0IGFuY2hvciA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2EnKVxuICAgICAgYW5jaG9yLmlubmVySFRNTCA9IGgyLmlubmVySFRNTFxuICAgICAgLy8gLnN1YnN0cmluZygxKSB3aWxsIHJlbW92ZSB0aGUgbGVhZGluZyAvIChwcmV2ZW50IGVycm9ycyB3aGVuIGJhc2VIcmVmIGlzIGRlZmluZWQgaW4gaW5kZXguaHRtbClcbiAgICAgIGFuY2hvci5ocmVmID0gdGhpcy5sb2NhdGlvbi5wYXRoKCkuc3Vic3RyaW5nKDEpICsgJyMnICsgaWRcblxuICAgICAgbGkuYXBwZW5kQ2hpbGQoYW5jaG9yKVxuICAgICAgdWwuYXBwZW5kQ2hpbGQobGkpXG5cbiAgICAgIGgyLnNldEF0dHJpYnV0ZSgnZGF0YS10b2MtaWQnLCBpZClcbiAgICAgIGxpLnNldEF0dHJpYnV0ZSgnZGF0YS10b2MtaWQnLCBpZClcblxuICAgICAgdGhpcy5hbmNob3JzLnB1c2gobGkpXG5cbiAgICAgIHRoaXMuaW50ZXJzZWN0aW9uPy5vYnNlcnZlKGgyKVxuICAgIH0pXG5cbiAgICB0b2NDb250YWluZXIuYXBwZW5kQ2hpbGQodWwpXG5cbiAgICBjb25zdCB7IGZyYWdtZW50IH0gPSB0aGlzLmFjdGl2YXRlZFJvdXRlLnNuYXBzaG90XG4gICAgaWYgKGZyYWdtZW50KSB7XG4gICAgICB0aGlzLnNjcm9sbChmcmFnbWVudClcbiAgICB9XG5cbiAgICB0aGlzLm9ic2VydmVyLm9ic2VydmUoY29tcG9uZW50Tm9kZSwge1xuICAgICAgY2hpbGRMaXN0OiB0cnVlLFxuICAgICAgc3VidHJlZTogdHJ1ZSxcbiAgICB9KVxuICB9XG5cbiAgcHJpdmF0ZSBkYXNoaWZ5KGlucHV0OiBzdHJpbmcpOiBzdHJpbmcge1xuICAgIHJldHVybiBpbnB1dFxuICAgICAgLnRyaW0oKVxuICAgICAgLnJlcGxhY2UoLyhbYS16XSkoW0EtWl0pL2csICckMS0kMicpXG4gICAgICAucmVwbGFjZSgvXFxXL2csIChtKSA9PiAoL1vDgC3Fvl0vLnRlc3QobSkgPyBtIDogJy0nKSlcbiAgICAgIC5yZXBsYWNlKC9eLSt8LSskL2csICcnKVxuICAgICAgLnJlcGxhY2UoLy17Mix9L2csIChtKSA9PiAnLScpIC8vIENvbmRlbnNlIG11bHRpcGxlIGNvbnNlY3V0aXZlIGRhc2hlcyB0byBvbmUuXG4gICAgICAudG9Mb3dlckNhc2UoKVxuICB9XG5cbiAgcHJpdmF0ZSBkZXRlY3RJbnRlcnNlY3Rpb24oKTogdm9pZCB7XG4gICAgY29uc3QgdG9jQ29udGFpbmVyID0gdGhpcy5lbGVtZW50UmVmLm5hdGl2ZUVsZW1lbnRcbiAgICBjb25zdCByZWN0ID0gdG9jQ29udGFpbmVyLmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpXG4gICAgY29uc3QgYm90dG9tID0gLXdpbmRvdy5pbm5lckhlaWdodCArIHJlY3QueSArIDIwMFxuXG4gICAgdGhpcy5pbnRlcnNlY3Rpb24/LmRpc2Nvbm5lY3QoKVxuICAgIHRoaXMuaW50ZXJzZWN0aW9uID0gbmV3IEludGVyc2VjdGlvbk9ic2VydmVyKFxuICAgICAgKGVudHJpZXMpID0+IHtcbiAgICAgICAgZW50cmllcy5mb3JFYWNoKChlbnRyeSkgPT4ge1xuICAgICAgICAgIGlmIChlbnRyeS5pc0ludGVyc2VjdGluZykge1xuICAgICAgICAgICAgdGhpcy5hbmNob3JzLmZvckVhY2goKGFuY2hvcikgPT4ge1xuICAgICAgICAgICAgICBhbmNob3IuY2xhc3NMaXN0LnJlbW92ZSgnYWN0aXZlJylcbiAgICAgICAgICAgICAgY29uc3QgYSA9IGFuY2hvci5nZXRBdHRyaWJ1dGUoJ2RhdGEtdG9jLWlkJylcbiAgICAgICAgICAgICAgY29uc3QgYiA9IGVudHJ5LnRhcmdldC5nZXRBdHRyaWJ1dGUoJ2RhdGEtdG9jLWlkJylcbiAgICAgICAgICAgICAgaWYgKGEgPT09IGIpIHtcbiAgICAgICAgICAgICAgICBhbmNob3IuY2xhc3NMaXN0LmFkZCgnYWN0aXZlJylcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSlcbiAgICAgICAgICB9XG4gICAgICAgIH0pXG4gICAgICB9LFxuICAgICAge1xuICAgICAgICAvLyBBIEJPWCBPRiAyMDBweCBTVEFSVElORyBBVCBUSEUgUE9TSVRJT04gT0YgVEhFIFRPQyBFTEVNRU5UXG4gICAgICAgIHJvb3RNYXJnaW46IGAwcHggMHB4ICR7Ym90dG9tfXB4IDBweGAsXG4gICAgICB9XG4gICAgKVxuICB9XG5cbiAgcHJpdmF0ZSBjbGVhcigpOiB2b2lkIHtcbiAgICBjb25zdCB0b2NDb250YWluZXIgPSB0aGlzLmVsZW1lbnRSZWYubmF0aXZlRWxlbWVudFxuICAgIHRvY0NvbnRhaW5lci5pbm5lckhUTUwgPSAnJ1xuICAgIHRoaXMub2JzZXJ2ZXIuZGlzY29ubmVjdCgpXG4gICAgdGhpcy5pbnRlcnNlY3Rpb24/LmRpc2Nvbm5lY3QoKVxuICAgIHRoaXMuYW5jaG9ycyA9IFtdXG4gIH1cblxuICBwcml2YXRlIHNjcm9sbChxdWVyeTogc3RyaW5nKTogdm9pZCB7XG4gICAgY29uc3QgdGFyZ2V0RWxlbWVudCA9IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoYGgyW2RhdGEtdG9jLWlkPVwiJHtxdWVyeX1cIl1gKVxuICAgIGlmICghdGFyZ2V0RWxlbWVudCkge1xuICAgICAgd2luZG93LnNjcm9sbFRvKDAsIDApXG4gICAgfSBlbHNlIGlmICghdGhpcy5pc0luVmlld3BvcnQodGFyZ2V0RWxlbWVudCkpIHtcbiAgICAgIHRhcmdldEVsZW1lbnQuc2Nyb2xsSW50b1ZpZXcoKVxuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgaXNJblZpZXdwb3J0KGVsZW06IGFueSk6IGJvb2xlYW4ge1xuICAgIGNvbnN0IGJvdW5kaW5nID0gZWxlbS5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKVxuICAgIHJldHVybiAoXG4gICAgICBib3VuZGluZy50b3AgPj0gMCAmJlxuICAgICAgYm91bmRpbmcubGVmdCA+PSAwICYmXG4gICAgICBib3VuZGluZy5ib3R0b20gPD0gKHdpbmRvdy5pbm5lckhlaWdodCB8fCBkb2N1bWVudC5kb2N1bWVudEVsZW1lbnQuY2xpZW50SGVpZ2h0KSAmJlxuICAgICAgYm91bmRpbmcucmlnaHQgPD0gKHdpbmRvdy5pbm5lcldpZHRoIHx8IGRvY3VtZW50LmRvY3VtZW50RWxlbWVudC5jbGllbnRXaWR0aClcbiAgICApXG4gIH1cbn1cbiJdfQ==