@miesil/pp-breadcrumbs
Version:
PP-Breadcrumbs is an Angular 7 module generating breadcrumbs based on the routing state.
291 lines (282 loc) • 9.51 kB
JavaScript
import { of, Observable, BehaviorSubject, concat, from } from 'rxjs';
import { template, templateSettings } from 'lodash';
import { filter, mergeMap, distinct, toArray, first, tap } from 'rxjs/operators';
import { Injectable, Injector, Component, EventEmitter, Output, NgModule, defineInjectable, inject, INJECTOR } from '@angular/core';
import { ActivatedRoute, NavigationEnd, Router, RouterModule } from '@angular/router';
import { CommonModule } from '@angular/common';
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
*/
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
*/
templateSettings.interpolate = /{{([\s\S]+?)}}/g;
class PpBreadcrumbsResolver {
/**
* @param {?} route
* @param {?} state
* @return {?}
*/
resolve(route, state) {
/** @type {?} */
const data = route.routeConfig.data;
/** @type {?} */
const path = this.getFullPath(route);
/** @type {?} */
const rawText = typeof data.breadcrumbs === 'string' ? data.breadcrumbs : data.breadcrumbs.text || data.text || path;
return of([
{
path: path,
text: this.stringFormat(rawText, route.data)
}
]);
}
/**
* @param {?} route
* @return {?}
*/
getFullPath(route) {
/** @type {?} */
const relativePath = (/**
* @param {?} segments
* @return {?}
*/
(segments) => segments.reduce((/**
* @param {?} a
* @param {?} v
* @return {?}
*/
(a, v) => (a += '/' + v.path)), ''));
/** @type {?} */
const fullPath = (/**
* @param {?} routes
* @return {?}
*/
(routes) => routes.reduce((/**
* @param {?} a
* @param {?} v
* @return {?}
*/
(a, v) => (a += relativePath(v.url))), ''));
return fullPath(route.pathFromRoot);
}
/**
* @private
* @param {?} templateString
* @param {?} binding
* @return {?}
*/
stringFormat(templateString, binding) {
/** @type {?} */
const compiled = template(templateString);
return compiled(binding);
}
}
PpBreadcrumbsResolver.decorators = [
{ type: Injectable }
];
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
*/
class PpBreadcrumbsService {
/**
* @param {?} router
* @param {?} route
* @param {?} injector
*/
constructor(router, route, injector) {
this.router = router;
this.injector = injector;
this.breadcrumbs = new BehaviorSubject([]);
this.defaultResolver = new PpBreadcrumbsResolver();
this.breadcrumbsSource = [];
this.router.events.pipe(filter((/**
* @param {?} x
* @return {?}
*/
x => x instanceof NavigationEnd))).subscribe((/**
* @param {?} event
* @return {?}
*/
(event) => {
this.resolveCrumbs(router.routerState.snapshot.root)
.pipe(mergeMap((/**
* @param {?} breadcrumbs
* @return {?}
*/
breadcrumbs => breadcrumbs)), distinct((/**
* @param {?} breadcrumb
* @return {?}
*/
breadcrumb => breadcrumb.text)), toArray(), tap((/**
* @param {?} breadcrumbs
* @return {?}
*/
breadcrumbs => this.breadcrumbsSource = breadcrumbs)), mergeMap((/**
* @param {?} breadcrumbs
* @return {?}
*/
breadcrumbs => {
return this.postProcess ? this.wrapIntoObservable(this.postProcess(breadcrumbs)).pipe(first()) : of(breadcrumbs);
})))
.subscribe((/**
* @param {?} breadcrumbs
* @return {?}
*/
breadcrumbs => {
this.breadcrumbs.next(breadcrumbs);
}));
}));
}
/**
* @return {?}
*/
get crumbs$() {
return this.breadcrumbs;
}
/**
* @return {?}
*/
refreshBreadcrumbs() {
(this.postProcess ? this.wrapIntoObservable(this.postProcess(this.breadcrumbsSource)).pipe(first()) : of(this.breadcrumbsSource))
.subscribe((/**
* @param {?} breadcrumbs
* @return {?}
*/
breadcrumbs => {
this.breadcrumbs.next(breadcrumbs);
}));
}
/**
* @private
* @param {?} route
* @return {?}
*/
resolveCrumbs(route) {
/** @type {?} */
let crumbs$ = of([]);
/** @type {?} */
const data = route.routeConfig && route.routeConfig.data;
if (data && data.breadcrumbs) {
/** @type {?} */
const resolver = data.breadcrumbs.prototype instanceof PpBreadcrumbsResolver ? this.injector.get(data.breadcrumbs) : this.defaultResolver;
/** @type {?} */
const result = resolver.resolve(route, this.router.routerState.snapshot);
crumbs$ = this.wrapIntoObservable(result).pipe(first());
}
return route.firstChild ? concat(crumbs$, this.resolveCrumbs(route.firstChild)) : crumbs$;
}
/**
* @private
* @template T
* @param {?} value
* @return {?}
*/
wrapIntoObservable(value) {
return value instanceof Observable ? value : this.isPromise(value) ? from(Promise.resolve(value)) : of((/** @type {?} */ (value)));
}
/**
* @private
* @param {?} value
* @return {?}
*/
isPromise(value) {
return value && typeof value.then === 'function';
}
}
PpBreadcrumbsService.decorators = [
{ type: Injectable, args: [{
providedIn: 'root'
},] }
];
/** @nocollapse */
PpBreadcrumbsService.ctorParameters = () => [
{ type: Router },
{ type: ActivatedRoute },
{ type: Injector }
];
/** @nocollapse */ PpBreadcrumbsService.ngInjectableDef = defineInjectable({ factory: function PpBreadcrumbsService_Factory() { return new PpBreadcrumbsService(inject(Router), inject(ActivatedRoute), inject(INJECTOR)); }, token: PpBreadcrumbsService, providedIn: "root" });
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
*/
class PpBreadcrumbsComponent {
/**
* @param {?} service
*/
constructor(service) {
this.service = service;
this.subscriptions = [];
this.onNavigate = new EventEmitter();
}
/**
* @return {?}
*/
ngOnInit() {
this.subscriptions.push(this.service.crumbs$.subscribe((/**
* @param {?} x
* @return {?}
*/
x => {
this.crumbs = x;
})));
}
/**
* @return {?}
*/
ngOnDestroy() {
this.subscriptions.forEach((/**
* @param {?} x
* @return {?}
*/
x => x.unsubscribe()));
this.onNavigate.complete();
this.onNavigate = undefined;
}
/**
* @return {?}
*/
click() {
this.onNavigate.emit({});
}
}
PpBreadcrumbsComponent.decorators = [
{ type: Component, args: [{
selector: 'pp-breadcrumbs',
template: "<ol *ngIf=\"crumbs.length\" class=\"breadcrumb\">\r\n <li *ngFor=\"let crumb of crumbs; let first = first; let last = last\" [ngClass]=\"{ 'active': last }\" class=\"breadcrumb-item\">\r\n <a *ngIf=\"!last; else lastBreadcrumb\" [routerLink]=\"crumb.path\" [innerHTML]=\"crumb.text\" (click)=\"click()\"></a>\r\n <ng-template #lastBreadcrumb>\r\n <span [innerHTML]=\"crumb.text\"></span>\r\n </ng-template>\r\n </li>\r\n</ol>\r\n",
styles: [""]
}] }
];
/** @nocollapse */
PpBreadcrumbsComponent.ctorParameters = () => [
{ type: PpBreadcrumbsService }
];
PpBreadcrumbsComponent.propDecorators = {
onNavigate: [{ type: Output }]
};
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
*/
class PpBreadcrumbsModule {
}
PpBreadcrumbsModule.decorators = [
{ type: NgModule, args: [{
declarations: [PpBreadcrumbsComponent],
imports: [CommonModule, RouterModule],
exports: [PpBreadcrumbsComponent]
},] }
];
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
*/
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
*/
export { PpBreadcrumbsService, PpBreadcrumbsComponent, PpBreadcrumbsResolver, PpBreadcrumbsModule };
//# sourceMappingURL=miesil-pp-breadcrumbs.js.map