ngx-breadcrumbs
Version:
Angular 4+ routing breadcrumbs
264 lines (255 loc) • 7.51 kB
JavaScript
import { Component, Injectable, Injector, NgModule } from '@angular/core';
import { ActivatedRoute, NavigationEnd, Router, RouterModule } from '@angular/router';
import { Observable as Observable$1 } from 'rxjs/Observable';
import { BehaviorSubject as BehaviorSubject$1 } from 'rxjs/BehaviorSubject';
import 'rxjs/add/observable/of';
import 'rxjs/add/operator/filter';
import 'rxjs/add/operator/concat';
import 'rxjs/add/operator/mergeMap';
import 'rxjs/add/operator/toArray';
import 'rxjs/add/operator/distinct';
import 'rxjs/add/operator/first';
import 'rxjs/add/observable/fromPromise';
import * as template from 'lodash.template';
import * as templateSettings from 'lodash.templatesettings';
import { CommonModule } from '@angular/common';
// Angular makes it impossible to make modules optional :(
// try {
// const _ = r('lodash');
// _template = _.template;
// _templateSettings = _.templateSetting
// } catch (e) {
// try {
// _template = r('lodash.template');
// _templateSettings = r('lodash.templatesettings');
// } catch (e) {
// _template = (y) => (x) => y;
// _templateSettings = {};
// }
// } finally {
// _templateSettings.interpolate = /{{([\s\S]+?)}}/g;
// }
const _ = {
template: template,
templateSettings: templateSettings
};
_.templateSettings.interpolate = /{{([\s\S]+?)}}/g;
/**
* @param {?} template
* @param {?} binding
* @return {?}
*/
function stringFormat(template$$1, binding) {
let /** @type {?} */ compiled = _.template(template$$1);
return compiled(binding);
}
/**
* @param {?} value
* @return {?}
*/
function isPromise(value) {
return value && (typeof value.then === 'function');
}
/**
* @template T
* @param {?} value
* @return {?}
*/
function wrapIntoObservable(value) {
if (value instanceof Observable$1)
return value;
if (isPromise(value)) {
return Observable$1.fromPromise(Promise.resolve(value));
}
return Observable$1.of(/** @type {?} */ (value));
}
class McBreadcrumbsConfig {
}
McBreadcrumbsConfig.decorators = [
{ type: Injectable },
];
/**
* @nocollapse
*/
McBreadcrumbsConfig.ctorParameters = () => [];
class McBreadcrumbsResolver {
/**
* @param {?} route
* @param {?} state
* @return {?}
*/
resolve(route, state) {
const /** @type {?} */ data = route.routeConfig.data;
const /** @type {?} */ path = this.getFullPath(route);
let /** @type {?} */ text = typeof (data.breadcrumbs) === 'string' ? data.breadcrumbs : data.breadcrumbs.text || data.text || path;
text = stringFormat(text, route.data);
const /** @type {?} */ crumbs = [{
text: text,
path: path
}];
return Observable$1.of(crumbs);
}
/**
* @param {?} route
* @return {?}
*/
getFullPath(route) {
const /** @type {?} */ relativePath = (segments) => segments.reduce((a, v) => a += '/' + v.path, '');
const /** @type {?} */ fullPath = (routes) => routes.reduce((a, v) => a += relativePath(v.url), '');
return fullPath(route.pathFromRoot);
}
}
class McBreadcrumbsService {
/**
* @param {?} _router
* @param {?} route
* @param {?} _config
* @param {?} _injector
*/
constructor(_router, route, _config, _injector) {
this._router = _router;
this._config = _config;
this._injector = _injector;
this._breadcrumbs = new BehaviorSubject$1([]);
this._defaultResolver = new McBreadcrumbsResolver();
this._router.events
.filter((x) => x instanceof NavigationEnd)
.subscribe((event) => {
const route = _router.routerState.snapshot.root;
//Observable.of(this._config.prefixCrumbs)
this._resolveCrumbs(route)
.flatMap((x) => x)
.distinct((x) => x.text)
.toArray()
.flatMap((x) => {
if (this._config.postProcess) {
const y = this._config.postProcess(x);
return wrapIntoObservable(y).first();
}
else {
return Observable$1.of(x);
}
})
.subscribe((x) => {
this._breadcrumbs.next(x);
});
});
}
/**
* @return {?}
*/
get crumbs$() {
return this._breadcrumbs;
}
/**
* @param {?} route
* @return {?}
*/
_resolveCrumbs(route) {
let /** @type {?} */ crumbs$;
const /** @type {?} */ data = route.routeConfig &&
route.routeConfig.data;
if (data && data.breadcrumbs) {
let /** @type {?} */ resolver;
if (data.breadcrumbs.prototype instanceof McBreadcrumbsResolver) {
resolver = this._injector.get(data.breadcrumbs);
}
else {
resolver = this._defaultResolver;
}
let /** @type {?} */ result = resolver.resolve(route, this._router.routerState.snapshot);
crumbs$ = wrapIntoObservable(result).first();
}
else {
crumbs$ = Observable$1.of([]);
}
if (route.firstChild) {
crumbs$ = crumbs$.concat(this._resolveCrumbs(route.firstChild));
}
return crumbs$;
}
}
McBreadcrumbsService.decorators = [
{ type: Injectable },
];
/**
* @nocollapse
*/
McBreadcrumbsService.ctorParameters = () => [
{ type: Router, },
{ type: ActivatedRoute, },
{ type: McBreadcrumbsConfig, },
{ type: Injector, },
];
class McBreadcrumbsComponent {
/**
* @param {?} service
*/
constructor(service) {
this.service = service;
this.subscriptions = new Array();
}
/**
* @return {?}
*/
ngOnInit() {
const /** @type {?} */ s = this.service.crumbs$.subscribe((x) => {
this.crumbs = x;
});
}
/**
* @return {?}
*/
ngOnDestroy() {
this.subscriptions.forEach((x) => x.unsubscribe());
}
}
McBreadcrumbsComponent.decorators = [
{ type: Component, args: [{
selector: 'mc-breadcrumbs',
template: `
<ol *ngIf="crumbs.length" class="breadcrumb">
<li *ngFor="let crumb of crumbs; let last = last" [ngClass]="{ 'active': last }" class="breadcrumb-item">
<a *ngIf="!last" [routerLink]="crumb.path">{{ crumb.text }}</a>
<span *ngIf="last">{{ crumb.text }}</span>
</li>
</ol>
`
},] },
];
/**
* @nocollapse
*/
McBreadcrumbsComponent.ctorParameters = () => [
{ type: McBreadcrumbsService, },
];
class McBreadcrumbsModule {
/**
* @return {?}
*/
static forRoot() {
return {
ngModule: McBreadcrumbsModule,
providers: [
McBreadcrumbsService,
McBreadcrumbsConfig
]
};
}
}
McBreadcrumbsModule.decorators = [
{ type: NgModule, args: [{
imports: [CommonModule, RouterModule],
declarations: [McBreadcrumbsComponent],
exports: [McBreadcrumbsComponent]
},] },
];
/**
* @nocollapse
*/
McBreadcrumbsModule.ctorParameters = () => [];
/**
* Generated bundle index. Do not edit.
*/
export { McBreadcrumbsComponent, McBreadcrumbsService, McBreadcrumbsConfig, McBreadcrumbsResolver, McBreadcrumbsModule };
//# sourceMappingURL=ngx-breadcrumbs.js.map