-
Notifications
You must be signed in to change notification settings - Fork 692
/
NavigationPlugin.ts
86 lines (75 loc) · 2.68 KB
/
NavigationPlugin.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
import { Component, RendererComponent } from '../components';
import { NavigationItem } from '../models/NavigationItem';
import { RendererEvent, PageEvent } from '../events';
/**
* A plugin that exposes the navigation structure of the documentation
* to the rendered templates.
*
* The navigation structure is generated using the current themes
* [[BaseTheme.getNavigation]] function. This plugins takes care that the navigation
* is updated and passed to the render context.
*/
@Component({name: 'navigation'})
export class NavigationPlugin extends RendererComponent {
/**
* The navigation structure generated by the current theme.
*/
navigation!: NavigationItem;
/**
* Create a new NavigationPlugin instance.
*/
initialize() {
this.listenTo(this.owner, {
[RendererEvent.BEGIN]: this.onBeginRenderer,
[PageEvent.BEGIN]: this.onBeginPage
});
}
/**
* Triggered before the renderer starts rendering a project.
*
* @param event An event object describing the current render operation.
*/
private onBeginRenderer(event: RendererEvent) {
this.navigation = this.owner.theme!.getNavigation(event.project);
}
/**
* Triggered before a document will be rendered.
*
* @param page An event object describing the current render operation.
*/
private onBeginPage(page: PageEvent) {
const currentItems: NavigationItem[] = [];
(function updateItem(item: NavigationItem) {
item.isCurrent = false;
item.isInPath = false;
item.isVisible = item.isGlobals;
if (item.url === page.url || (item.dedicatedUrls && item.dedicatedUrls.includes(page.url))) {
currentItems.push(item);
}
if (item.children) {
item.children.forEach((child) => updateItem(child));
}
})(this.navigation);
currentItems.forEach((item: NavigationItem | undefined) => {
item!.isCurrent = true;
let depth = item!.isGlobals ? -1 : 0;
let count = 1;
while (item) {
item.isInPath = true;
item.isVisible = true;
count += 1;
depth += 1;
if (item.children) {
count += item.children.length;
if (depth < 2 || count < 30) {
item.children.forEach((child) => {
child.isVisible = true;
});
}
}
item = item.parent;
}
});
page.navigation = this.navigation;
}
}