-
Notifications
You must be signed in to change notification settings - Fork 1
/
index.js
146 lines (132 loc) · 3.79 KB
/
index.js
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
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
'use strict';
var env = require( 'jsdoc/env' );
// We use this only for debugging
// var logger = require( 'jsdoc/util/logger' );
var conf = env.conf.opts[ 'class-hierarchy' ] || {};
var showList = conf.showList === undefined ? false : conf.showList;
// Key map of classes and what they inherit from:
// { 'childClassName': 'parentClassName' }
var parents = {};
/**
* A recursive function that finds all the parents of a given class.
*
* @param {string[]} p A single element array with the name of the class
* whose parents we need to find
* @returns {string[]} An array of all parents starting with the highest
*/
function findAllParents( p ) {
var lastParent = p[ 0 ];
var lastParentsParent = parents[ lastParent ];
if ( lastParentsParent === undefined ) {
return p;
} else {
p.unshift( lastParentsParent );
return findAllParents( p );
}
}
/**
* Finds all the direct children of a given class name.
*
* @param {string} className
* @returns {string[]} Array of the child classes' names
*/
function findDirectChildren( className ) {
var children = [];
for ( var longname in parents ) {
if ( parents[ longname ] === className ) {
children.push( longname );
}
}
return children;
}
/**
* Creates a link to a given class.
*
* @param {string} className
* @returns {string} HTML string of '<a>'
*/
function linkTo( className ) {
return '<a href="' + className + '.html">' + className + '</a>';
}
/**
* Recursive function that creates a nested list of a class' parents.
*
* @param {string[]} classes Array of class' parent's names
* @returns {string} HTML string of a `<ul>`
*/
function makeHierarchyList( classes ) {
if ( classes.length === 0 ) {
return '';
} else {
var className = classes.shift();
return '<ul><li>' + linkTo( className ) + ' ' + makeHierarchyList( classes ) + '</li></ul>'
}
}
/**
* Creates a list of child classes.
*
* @param {string[]} classes Array of all the child classes' names.
* @returns {string} HTML string of a `<ul>`
*/
function makeChildrenList( classes ) {
var list = '<ul>';
classes.forEach( function ( className ) {
list += '<li>' + linkTo( className ) + '</li>';
})
list += '</ul>';
return list;
}
// Setup event handlers for JSDoc
exports.handlers = {
// Add names to the parents map for every new doclet
newDoclet: function ( e ) {
var doclet = e.doclet;
if (
doclet.kind === 'class' &&
doclet.augments !== undefined &&
doclet.augments.length > 0
) {
parents[ doclet.longname ] = doclet.augments[ 0 ];
}
},
// Once all doclets are processed, go through them and create hierarchy
// and children lists. Also add the HTML versions if the config allows.
processingComplete: function(e) {
// Traverse list and get all parents
e.doclets.forEach( function (d) {
if ( d.kind === 'class' ) {
var html = '';
if (
d.augments !== undefined &&
d.augments.length > 0
) {
d.hierarchy = findAllParents( [ d.longname ] );
if ( d.hierarchy.length > 0 && showList ) {
html += '<h3 style="margin:0;">Hierarchy</h3>' + makeHierarchyList( d.hierarchy.slice() );
}
}
d.children = findDirectChildren( d.longname );
if ( d.children.length > 0 && showList ) {
html += '<h3 style="margin:0;">Children</h3>' + makeChildrenList( d.children.slice() );
}
if (
showList &&
(
( d.children && d.children.length > 0 ) ||
( d.hierarchy && d.hierarchy.length > 0 )
)
) {
d.description = d.description === undefined ? '' : d.description;
// Otherwise, using += appends 'undefined' as a string
d.description = '<div style="' +
'border: 1px solid #c8ccd1;' +
'background:#eaecf0;' +
'padding: 10px;' +
'font-size: x-small;' +
'float: right;' +
'">' + html + '</div>' + d.description;
}
}
});
}
};