@qubit-ltd/jsdoc-theme 1.3.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +260 -0
- package/LICENSE +21 -0
- package/README.md +798 -0
- package/clean-jsdoc-theme-defaults.js +37 -0
- package/clean-jsdoc-theme-helper.js +186 -0
- package/helpers/Environment.html +3 -0
- package/helpers/down-arrow.js +9 -0
- package/helpers/i18n.js +106 -0
- package/i18n/en.json +76 -0
- package/i18n/zh.json +76 -0
- package/package.json +83 -0
- package/publish.js +1133 -0
- package/static/fonts/Inconsolata-Regular.ttf +0 -0
- package/static/fonts/OpenSans-Regular.ttf +0 -0
- package/static/fonts/WorkSans-Bold.ttf +0 -0
- package/static/scripts/core.js +720 -0
- package/static/scripts/core.min.js +23 -0
- package/static/scripts/resize.js +90 -0
- package/static/scripts/search.js +269 -0
- package/static/scripts/search.min.js +6 -0
- package/static/scripts/third-party/Apache-License-2.0.txt +202 -0
- package/static/scripts/third-party/fuse.js +1749 -0
- package/static/scripts/third-party/hljs-line-num-original.js +367 -0
- package/static/scripts/third-party/hljs-line-num.js +1 -0
- package/static/scripts/third-party/hljs-original.js +5260 -0
- package/static/scripts/third-party/hljs.js +1 -0
- package/static/scripts/third-party/popper.js +1287 -0
- package/static/scripts/third-party/tippy.js +1499 -0
- package/static/scripts/third-party/tocbot.js +757 -0
- package/static/scripts/third-party/tocbot.min.js +1 -0
- package/static/styles/clean-jsdoc-theme-base.css +1257 -0
- package/static/styles/clean-jsdoc-theme-dark.css +412 -0
- package/static/styles/clean-jsdoc-theme-light.css +482 -0
- package/static/styles/clean-jsdoc-theme-scrollbar.css +30 -0
- package/static/styles/clean-jsdoc-theme-without-scrollbar.min.css +1 -0
- package/static/styles/clean-jsdoc-theme.min.css +1 -0
- package/tmpl/augments.tmpl +10 -0
- package/tmpl/container.tmpl +261 -0
- package/tmpl/details.tmpl +207 -0
- package/tmpl/example.tmpl +3 -0
- package/tmpl/examples.tmpl +48 -0
- package/tmpl/exceptions.tmpl +32 -0
- package/tmpl/i18n-tooltips.tmpl +30 -0
- package/tmpl/icons.tmpl +77 -0
- package/tmpl/include-target-script-and-styles.tmpl +43 -0
- package/tmpl/layout.tmpl +169 -0
- package/tmpl/mainpage.tmpl +10 -0
- package/tmpl/members.tmpl +42 -0
- package/tmpl/method.tmpl +190 -0
- package/tmpl/mobile-sidebar.tmpl +21 -0
- package/tmpl/navbar-actions.tmpl +25 -0
- package/tmpl/navbar-menu.tmpl +25 -0
- package/tmpl/navbar.tmpl +14 -0
- package/tmpl/params.tmpl +131 -0
- package/tmpl/properties.tmpl +109 -0
- package/tmpl/returns.tmpl +19 -0
- package/tmpl/search.tmpl +17 -0
- package/tmpl/sidebar-items.tmpl +33 -0
- package/tmpl/sidebar-title.tmpl +8 -0
- package/tmpl/sidebar.tmpl +9 -0
- package/tmpl/source.tmpl +13 -0
- package/tmpl/toc.tmpl +4 -0
- package/tmpl/tutorial.tmpl +32 -0
- package/tmpl/type.tmpl +13 -0
package/publish.js
ADDED
|
@@ -0,0 +1,1133 @@
|
|
|
1
|
+
console.log("🔥🔥🔥 PUBLISH.JS IS BEING CALLED! 🔥🔥🔥");
|
|
2
|
+
|
|
3
|
+
const _ = require("lodash");
|
|
4
|
+
const env = require("jsdoc/env");
|
|
5
|
+
const fs = require("fs-extra");
|
|
6
|
+
const helper = require("jsdoc/util/templateHelper");
|
|
7
|
+
const logger = require("jsdoc/util/logger");
|
|
8
|
+
const path = require("jsdoc/path");
|
|
9
|
+
const { taffy } = require("@jsdoc/salty");
|
|
10
|
+
const template = require("jsdoc/template");
|
|
11
|
+
const htmlMinify = require("html-minifier-terser");
|
|
12
|
+
|
|
13
|
+
const {
|
|
14
|
+
buildFooter,
|
|
15
|
+
codepen,
|
|
16
|
+
createDynamicStyleSheet,
|
|
17
|
+
createDynamicsScripts,
|
|
18
|
+
getBaseURL,
|
|
19
|
+
getFavicon,
|
|
20
|
+
getMetaTagData,
|
|
21
|
+
getTheme,
|
|
22
|
+
includeCss,
|
|
23
|
+
includeScript,
|
|
24
|
+
moduleHeader,
|
|
25
|
+
resizeable,
|
|
26
|
+
returnPathOfScriptScr,
|
|
27
|
+
returnPathOfStyleSrc,
|
|
28
|
+
copyStaticFolder,
|
|
29
|
+
getProcessedYield,
|
|
30
|
+
lsSync,
|
|
31
|
+
} = require("./clean-jsdoc-theme-helper");
|
|
32
|
+
|
|
33
|
+
const i18n = require("./helpers/i18n");
|
|
34
|
+
|
|
35
|
+
const {
|
|
36
|
+
HTML_MINIFY_OPTIONS,
|
|
37
|
+
SECTION_TYPE,
|
|
38
|
+
defaultSections,
|
|
39
|
+
} = require("./clean-jsdoc-theme-defaults");
|
|
40
|
+
|
|
41
|
+
const htmlsafe = helper.htmlsafe;
|
|
42
|
+
const linkto = helper.linkto;
|
|
43
|
+
const resolveAuthorLinks = helper.resolveAuthorLinks;
|
|
44
|
+
const hasOwnProp = Object.prototype.hasOwnProperty;
|
|
45
|
+
|
|
46
|
+
const themeOpts = (env && env.opts && env.opts.theme_opts) || {};
|
|
47
|
+
|
|
48
|
+
let data;
|
|
49
|
+
let view;
|
|
50
|
+
/**
|
|
51
|
+
* @type {Array<{title: string, link: string, description: string}>}
|
|
52
|
+
*/
|
|
53
|
+
const searchList = [];
|
|
54
|
+
const hasSearch =
|
|
55
|
+
themeOpts.search === undefined ? true : Boolean(themeOpts.search);
|
|
56
|
+
|
|
57
|
+
// eslint-disable-next-line no-restricted-globals
|
|
58
|
+
let outdir = path.resolve(path.normalize(env.opts.destination));
|
|
59
|
+
|
|
60
|
+
function mkdirSync(filepath) {
|
|
61
|
+
return fs.mkdirSync(filepath, { recursive: true });
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
function sourceToDestination(parentDir, sourcePath, destDir) {
|
|
65
|
+
const relativeSource = path.relative(parentDir, sourcePath);
|
|
66
|
+
|
|
67
|
+
return path.resolve(path.join(destDir, relativeSource));
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
function find(spec) {
|
|
71
|
+
return helper.find(data, spec);
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
function tutoriallink(tutorial) {
|
|
75
|
+
return helper.toTutorial(tutorial, null, {
|
|
76
|
+
tag: "em",
|
|
77
|
+
classname: "disabled",
|
|
78
|
+
prefix: "Tutorial: ",
|
|
79
|
+
});
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
function getAncestorLinks(doclet) {
|
|
83
|
+
return helper.getAncestorLinks(data, doclet);
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
function hashToLink(doclet, hash, dependencies) {
|
|
87
|
+
let url;
|
|
88
|
+
|
|
89
|
+
if (!/^(#.+)/.test(hash)) {
|
|
90
|
+
return hash;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
url = helper.createLink(doclet, dependencies);
|
|
94
|
+
url = url.replace(/(#.+|$)/, hash);
|
|
95
|
+
|
|
96
|
+
return `<a href="${url}">${hash}</a>`;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
function needsSignature({ kind, type, meta }) {
|
|
100
|
+
let needsSig = false;
|
|
101
|
+
|
|
102
|
+
// function and class definitions always get a signature
|
|
103
|
+
if (kind === "function" || kind === "class") {
|
|
104
|
+
needsSig = true;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
// typedefs that contain functions get a signature, too
|
|
108
|
+
else if (kind === "typedef" && type && type.names && type.names.length) {
|
|
109
|
+
for (let i = 0, l = type.names.length; i < l; i++) {
|
|
110
|
+
if (type.names[i].toLowerCase() === "function") {
|
|
111
|
+
needsSig = true;
|
|
112
|
+
break;
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
// and namespaces that are functions get a signature (but finding them is a
|
|
118
|
+
// bit messy)
|
|
119
|
+
else if (
|
|
120
|
+
kind === "namespace" &&
|
|
121
|
+
meta &&
|
|
122
|
+
meta.code &&
|
|
123
|
+
meta.code.type &&
|
|
124
|
+
meta.code.type.match(/[Ff]unction/)
|
|
125
|
+
) {
|
|
126
|
+
needsSig = true;
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
return needsSig;
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
function getSignatureAttributes({ optional, nullable }) {
|
|
133
|
+
const attributes = [];
|
|
134
|
+
|
|
135
|
+
if (optional) {
|
|
136
|
+
attributes.push("opt");
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
if (nullable === true) {
|
|
140
|
+
attributes.push("nullable");
|
|
141
|
+
} else if (nullable === false) {
|
|
142
|
+
attributes.push("non-null");
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
return attributes;
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
function updateItemName(item) {
|
|
149
|
+
const attributes = getSignatureAttributes(item);
|
|
150
|
+
let itemName = item.name || "";
|
|
151
|
+
|
|
152
|
+
if (item.variable) {
|
|
153
|
+
itemName = "…" + itemName;
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
if (attributes && attributes.length) {
|
|
157
|
+
itemName = `${itemName}<span class="signature-attributes">${attributes.join(
|
|
158
|
+
", "
|
|
159
|
+
)}</span>`;
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
return itemName;
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
function addParamAttributes(params) {
|
|
166
|
+
return params
|
|
167
|
+
.filter(({ name }) => name && !name.includes("."))
|
|
168
|
+
.map(updateItemName);
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
function buildItemTypeStrings(item) {
|
|
172
|
+
const types = [];
|
|
173
|
+
|
|
174
|
+
if (item && item.type && item.type.names) {
|
|
175
|
+
item.type.names.forEach(function (name) {
|
|
176
|
+
types.push(linkto(name, htmlsafe(name)));
|
|
177
|
+
});
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
return types;
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
function buildAttribsString(attribs) {
|
|
184
|
+
let attribsString = "";
|
|
185
|
+
|
|
186
|
+
if (attribs && attribs.length) {
|
|
187
|
+
attribsString = htmlsafe(`(${attribs.join(", ")}) `);
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
return attribsString;
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
function addNonParamAttributes(items) {
|
|
194
|
+
let types = [];
|
|
195
|
+
|
|
196
|
+
items.forEach(function (item) {
|
|
197
|
+
types = types.concat(buildItemTypeStrings(item));
|
|
198
|
+
});
|
|
199
|
+
|
|
200
|
+
return types;
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
function addSignatureParams(f) {
|
|
204
|
+
const params = f.params ? addParamAttributes(f.params) : [];
|
|
205
|
+
|
|
206
|
+
f.signature = `${f.signature || ""}(${params.join(", ")})`;
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
function addSignatureReturns(f) {
|
|
210
|
+
const attribs = [];
|
|
211
|
+
let attribsString = "";
|
|
212
|
+
let returnTypes = [];
|
|
213
|
+
let returnTypesString = "";
|
|
214
|
+
const source = f.yields || f.returns;
|
|
215
|
+
|
|
216
|
+
// jam all the return-type attributes into an array. this could create odd results (for example,
|
|
217
|
+
// if there are both nullable and non-nullable return types), but let's assume that most people
|
|
218
|
+
// who use multiple @return tags aren't using Closure Compiler type annotations, and vice-versa.
|
|
219
|
+
if (source) {
|
|
220
|
+
source.forEach((item) => {
|
|
221
|
+
helper.getAttribs(item).forEach((attrib) => {
|
|
222
|
+
if (!attribs.includes(attrib)) {
|
|
223
|
+
attribs.push(attrib);
|
|
224
|
+
}
|
|
225
|
+
});
|
|
226
|
+
});
|
|
227
|
+
|
|
228
|
+
attribsString = buildAttribsString(attribs);
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
if (source) {
|
|
232
|
+
returnTypes = addNonParamAttributes(source);
|
|
233
|
+
}
|
|
234
|
+
if (returnTypes.length) {
|
|
235
|
+
returnTypesString = ` → ${attribsString}{${returnTypes.join("|")}}`;
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
let signatureOutput = "";
|
|
239
|
+
|
|
240
|
+
if (f.signature) {
|
|
241
|
+
signatureOutput =
|
|
242
|
+
'<span class="signature">' + (f.signature || "") + "</span>";
|
|
243
|
+
}
|
|
244
|
+
if (returnTypesString) {
|
|
245
|
+
signatureOutput +=
|
|
246
|
+
'<span class="type-signature">' + returnTypesString + "</span>";
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
f.signature = signatureOutput;
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
function addSignatureTypes(f) {
|
|
253
|
+
const types = f.type ? buildItemTypeStrings(f) : [];
|
|
254
|
+
|
|
255
|
+
f.signature =
|
|
256
|
+
`${f.signature || ""}<span class="type-signature">` +
|
|
257
|
+
`${types.length ? ` :${types.join("|")}` : ""}</span>`;
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
function addAttribs(f) {
|
|
261
|
+
const attribs = helper.getAttribs(f);
|
|
262
|
+
const attribsString = buildAttribsString(attribs);
|
|
263
|
+
|
|
264
|
+
f.attribs = `<span class="type-signature">${attribsString}</span>`;
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
function shortenPaths(files, commonPrefix) {
|
|
268
|
+
Object.keys(files).forEach(function (file) {
|
|
269
|
+
files[file].shortened = files[file].resolved
|
|
270
|
+
.replace(commonPrefix, "")
|
|
271
|
+
// always use forward slashes
|
|
272
|
+
.replace(/\\/g, "/");
|
|
273
|
+
});
|
|
274
|
+
|
|
275
|
+
return files;
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
function getPathFromDoclet({ meta }) {
|
|
279
|
+
if (!meta) {
|
|
280
|
+
return null;
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
return meta.path && meta.path !== "null"
|
|
284
|
+
? path.join(meta.path, meta.filename)
|
|
285
|
+
: meta.filename;
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
function createPrettyAnchor(elementType, ancestor, name, href) {
|
|
289
|
+
return `<${elementType} ${href ? `href="${href}"` : ""} class="has-anchor">
|
|
290
|
+
<span class="ancestors">
|
|
291
|
+
${ancestor}~
|
|
292
|
+
</span>
|
|
293
|
+
${name}
|
|
294
|
+
</${elementType}>`;
|
|
295
|
+
}
|
|
296
|
+
|
|
297
|
+
function prefixModuleToItemAnchor(item) {
|
|
298
|
+
let { anchor } = item;
|
|
299
|
+
|
|
300
|
+
let anchorLink = anchor.split('href="')[1].split('"')[0];
|
|
301
|
+
let cleanLink = anchorLink.replace(/\.html$/, "");
|
|
302
|
+
|
|
303
|
+
let prettyAnchor;
|
|
304
|
+
|
|
305
|
+
cleanLink.replace(
|
|
306
|
+
/module-([^-]+)(?:-|\.)(.*)/,
|
|
307
|
+
(_match, modulename, methodname) => {
|
|
308
|
+
prettyAnchor = createPrettyAnchor(
|
|
309
|
+
"a",
|
|
310
|
+
modulename,
|
|
311
|
+
methodname,
|
|
312
|
+
anchorLink
|
|
313
|
+
);
|
|
314
|
+
}
|
|
315
|
+
);
|
|
316
|
+
|
|
317
|
+
return prettyAnchor || anchor;
|
|
318
|
+
}
|
|
319
|
+
|
|
320
|
+
async function generate(title, docs, filename, resolveLinks, packageInfo) {
|
|
321
|
+
let docData;
|
|
322
|
+
let html;
|
|
323
|
+
let outpath;
|
|
324
|
+
|
|
325
|
+
docData = {
|
|
326
|
+
env: env,
|
|
327
|
+
title: title,
|
|
328
|
+
docs: docs,
|
|
329
|
+
filename,
|
|
330
|
+
t: i18n.t,
|
|
331
|
+
currentLanguage: i18n.getCurrentLanguage(),
|
|
332
|
+
packageInfo: packageInfo,
|
|
333
|
+
};
|
|
334
|
+
|
|
335
|
+
outpath = path.join(outdir, filename);
|
|
336
|
+
console.log("🚀🚀🚀 ABOUT TO RENDER CONTAINER.TMPL for:", filename, "🚀🚀🚀");
|
|
337
|
+
console.log(
|
|
338
|
+
"🔍 docData.docs[0].kind:",
|
|
339
|
+
docData.docs && docData.docs[0] ? docData.docs[0].kind : "NO DOCS"
|
|
340
|
+
);
|
|
341
|
+
console.log("🔍 packageInfo:", JSON.stringify(docData.packageInfo));
|
|
342
|
+
html = view.render("container.tmpl", docData);
|
|
343
|
+
|
|
344
|
+
if (resolveLinks !== false) {
|
|
345
|
+
html = helper.resolveLinks(html); // turn {@link foo} into <a href="foodoc.html">foo</a>
|
|
346
|
+
}
|
|
347
|
+
|
|
348
|
+
const minifiedHtml = await htmlMinify.minify(html, HTML_MINIFY_OPTIONS);
|
|
349
|
+
|
|
350
|
+
fs.writeFileSync(outpath, minifiedHtml, "utf8");
|
|
351
|
+
}
|
|
352
|
+
|
|
353
|
+
function generateSourceFiles(sourceFiles, packageInfo, encoding = "utf8") {
|
|
354
|
+
Object.keys(sourceFiles).forEach(function (file) {
|
|
355
|
+
let source;
|
|
356
|
+
// links are keyed to the shortened path in each doclet's `meta.shortpath` property
|
|
357
|
+
const sourceOutFile = helper.getUniqueFilename(sourceFiles[file].shortened);
|
|
358
|
+
|
|
359
|
+
helper.registerLink(sourceFiles[file].shortened, sourceOutFile);
|
|
360
|
+
|
|
361
|
+
try {
|
|
362
|
+
source = {
|
|
363
|
+
kind: "source",
|
|
364
|
+
title: sourceOutFile.replace(".html", ""),
|
|
365
|
+
code: helper.htmlsafe(
|
|
366
|
+
fs.readFileSync(sourceFiles[file].resolved, encoding)
|
|
367
|
+
),
|
|
368
|
+
};
|
|
369
|
+
} catch (e) {
|
|
370
|
+
logger.error(
|
|
371
|
+
"Error while generating source file %s: %s",
|
|
372
|
+
file,
|
|
373
|
+
e.message
|
|
374
|
+
);
|
|
375
|
+
}
|
|
376
|
+
|
|
377
|
+
generate(
|
|
378
|
+
`Source: ${sourceFiles[file].shortened}`,
|
|
379
|
+
[source],
|
|
380
|
+
sourceOutFile,
|
|
381
|
+
false,
|
|
382
|
+
packageInfo
|
|
383
|
+
);
|
|
384
|
+
});
|
|
385
|
+
}
|
|
386
|
+
|
|
387
|
+
/**
|
|
388
|
+
* Look for classes or functions with the same name as modules (which indicates that the module
|
|
389
|
+
* exports only that class or function), then attach the classes or functions to the `module`
|
|
390
|
+
* property of the appropriate module doclets. The name of each class or function is also updated
|
|
391
|
+
* for display purposes. This function mutates the original arrays.
|
|
392
|
+
*
|
|
393
|
+
* @private
|
|
394
|
+
* @param {Array.<module:jsdoc/doclet.Doclet>} doclets - The array of classes and functions to
|
|
395
|
+
* check.
|
|
396
|
+
* @param {Array.<module:jsdoc/doclet.Doclet>} modules - The array of module doclets to search.
|
|
397
|
+
*/
|
|
398
|
+
function attachModuleSymbols(doclets, modules) {
|
|
399
|
+
const symbols = {};
|
|
400
|
+
|
|
401
|
+
// build a lookup table
|
|
402
|
+
doclets.forEach((symbol) => {
|
|
403
|
+
symbols[symbol.longname] = symbols[symbol.longname] || [];
|
|
404
|
+
symbols[symbol.longname].push(symbol);
|
|
405
|
+
});
|
|
406
|
+
|
|
407
|
+
modules.forEach((module) => {
|
|
408
|
+
if (symbols[module.longname]) {
|
|
409
|
+
module.modules = symbols[module.longname]
|
|
410
|
+
// Only show symbols that have a description. Make an exception for classes, because
|
|
411
|
+
// we want to show the constructor-signature heading no matter what.
|
|
412
|
+
.filter(({ description, kind }) => description || kind === "class")
|
|
413
|
+
.map((symbol) => {
|
|
414
|
+
symbol = _.cloneDeep(symbol);
|
|
415
|
+
|
|
416
|
+
if (symbol.kind === "class" || symbol.kind === "function") {
|
|
417
|
+
symbol.name = `${symbol.name.replace("module:", '(require("')}"))`;
|
|
418
|
+
}
|
|
419
|
+
|
|
420
|
+
return symbol;
|
|
421
|
+
});
|
|
422
|
+
}
|
|
423
|
+
});
|
|
424
|
+
}
|
|
425
|
+
|
|
426
|
+
function buildSidebarMembers({
|
|
427
|
+
items,
|
|
428
|
+
itemHeading,
|
|
429
|
+
itemsSeen,
|
|
430
|
+
linktoFn,
|
|
431
|
+
sectionName,
|
|
432
|
+
}) {
|
|
433
|
+
const navProps = {
|
|
434
|
+
name: itemHeading,
|
|
435
|
+
items: [],
|
|
436
|
+
id: `sidebar-${itemHeading.toLowerCase()}`,
|
|
437
|
+
};
|
|
438
|
+
|
|
439
|
+
if (items.length) {
|
|
440
|
+
items.forEach(function (item) {
|
|
441
|
+
const currentItem = {
|
|
442
|
+
name: item.name,
|
|
443
|
+
anchor: item.longname
|
|
444
|
+
? linktoFn(item.longname, item.name)
|
|
445
|
+
: linktoFn("", item.name),
|
|
446
|
+
children: [],
|
|
447
|
+
};
|
|
448
|
+
|
|
449
|
+
const methods =
|
|
450
|
+
sectionName === SECTION_TYPE.Tutorials ||
|
|
451
|
+
sectionName === SECTION_TYPE.Global
|
|
452
|
+
? []
|
|
453
|
+
: find({
|
|
454
|
+
kind: "function",
|
|
455
|
+
memberof: item.longname,
|
|
456
|
+
inherited: {
|
|
457
|
+
"!is": Boolean(themeOpts.exclude_inherited),
|
|
458
|
+
},
|
|
459
|
+
});
|
|
460
|
+
|
|
461
|
+
if (!hasOwnProp.call(itemsSeen, item.longname)) {
|
|
462
|
+
currentItem.anchor = linktoFn(
|
|
463
|
+
item.longname,
|
|
464
|
+
item.name.replace(/^module:/, "")
|
|
465
|
+
);
|
|
466
|
+
|
|
467
|
+
if (methods.length) {
|
|
468
|
+
methods.forEach(function (method) {
|
|
469
|
+
const itemChild = {
|
|
470
|
+
name: method.longName,
|
|
471
|
+
link: linktoFn(method.longname, method.name),
|
|
472
|
+
};
|
|
473
|
+
|
|
474
|
+
currentItem.children.push(itemChild);
|
|
475
|
+
});
|
|
476
|
+
}
|
|
477
|
+
itemsSeen[item.longname] = true;
|
|
478
|
+
}
|
|
479
|
+
|
|
480
|
+
navProps.items.push(currentItem);
|
|
481
|
+
});
|
|
482
|
+
}
|
|
483
|
+
|
|
484
|
+
return navProps;
|
|
485
|
+
}
|
|
486
|
+
|
|
487
|
+
function buildSearchListForData() {
|
|
488
|
+
data().each((item) => {
|
|
489
|
+
if (item.kind !== "package" && !item.inherited) {
|
|
490
|
+
searchList.push({
|
|
491
|
+
title: item.longname,
|
|
492
|
+
link: linkto(item.longname, item.name),
|
|
493
|
+
description: item.description,
|
|
494
|
+
});
|
|
495
|
+
}
|
|
496
|
+
});
|
|
497
|
+
}
|
|
498
|
+
|
|
499
|
+
function linktoTutorial(longName, name) {
|
|
500
|
+
return tutoriallink(name);
|
|
501
|
+
}
|
|
502
|
+
|
|
503
|
+
function linktoExternal(longName, name) {
|
|
504
|
+
return linkto(longName, name.replace(/(^"|"$)/g, ""));
|
|
505
|
+
}
|
|
506
|
+
|
|
507
|
+
/**
|
|
508
|
+
* This function is added by clean-jsdoc-theme devs
|
|
509
|
+
* This function is added by clean-jsdoc-theme devs
|
|
510
|
+
* This function is added by clean-jsdoc-theme devs
|
|
511
|
+
*
|
|
512
|
+
*/
|
|
513
|
+
function buildNavbar() {
|
|
514
|
+
return {
|
|
515
|
+
menu: themeOpts.menu || undefined,
|
|
516
|
+
search: hasSearch,
|
|
517
|
+
};
|
|
518
|
+
}
|
|
519
|
+
|
|
520
|
+
/**
|
|
521
|
+
* This function is added by clean-jsdoc-theme devs
|
|
522
|
+
* This function is added by clean-jsdoc-theme devs
|
|
523
|
+
* This function is added by clean-jsdoc-theme devs
|
|
524
|
+
*
|
|
525
|
+
* @param {object} members The members that will be used to create the sidebar.
|
|
526
|
+
* @param {array<object>} members.classes
|
|
527
|
+
* @param {array<object>} members.externals
|
|
528
|
+
* @param {array<object>} members.globals
|
|
529
|
+
* @param {array<object>} members.mixins
|
|
530
|
+
* @param {array<object>} members.modules
|
|
531
|
+
* @param {array<object>} members.namespaces
|
|
532
|
+
* @param {array<object>} members.tutorials
|
|
533
|
+
* @param {array<object>} members.events
|
|
534
|
+
* @param {array<object>} members.interfaces
|
|
535
|
+
* @return {string} The HTML for the navigation sidebar.
|
|
536
|
+
*/
|
|
537
|
+
function buildSidebar(members) {
|
|
538
|
+
const title = themeOpts.title;
|
|
539
|
+
|
|
540
|
+
const isHTML = RegExp.prototype.test.bind(/(<([^>]+)>)/i);
|
|
541
|
+
|
|
542
|
+
const nav = {
|
|
543
|
+
sections: [],
|
|
544
|
+
};
|
|
545
|
+
|
|
546
|
+
if (!isHTML(title)) {
|
|
547
|
+
nav.title = {
|
|
548
|
+
title,
|
|
549
|
+
isHTML: false,
|
|
550
|
+
};
|
|
551
|
+
} else {
|
|
552
|
+
nav.title = {
|
|
553
|
+
title,
|
|
554
|
+
isHTML: true,
|
|
555
|
+
};
|
|
556
|
+
}
|
|
557
|
+
|
|
558
|
+
const seen = {};
|
|
559
|
+
const seenTutorials = {};
|
|
560
|
+
const seenGlobal = {};
|
|
561
|
+
|
|
562
|
+
const sectionsOrder = themeOpts.sections || defaultSections;
|
|
563
|
+
|
|
564
|
+
const sections = {
|
|
565
|
+
[SECTION_TYPE.Modules]: buildSidebarMembers({
|
|
566
|
+
itemHeading: "Modules",
|
|
567
|
+
items: members.modules,
|
|
568
|
+
itemsSeen: seen,
|
|
569
|
+
linktoFn: linkto,
|
|
570
|
+
sectionName: SECTION_TYPE.Modules,
|
|
571
|
+
}),
|
|
572
|
+
|
|
573
|
+
[SECTION_TYPE.Classes]: buildSidebarMembers({
|
|
574
|
+
itemHeading: i18n.t("classes", "Classes"),
|
|
575
|
+
items: members.classes,
|
|
576
|
+
itemsSeen: seen,
|
|
577
|
+
linktoFn: linkto,
|
|
578
|
+
sectionName: SECTION_TYPE.Classes,
|
|
579
|
+
}),
|
|
580
|
+
|
|
581
|
+
[SECTION_TYPE.Externals]: buildSidebarMembers({
|
|
582
|
+
itemHeading: "Externals",
|
|
583
|
+
items: members.externals,
|
|
584
|
+
itemsSeen: seen,
|
|
585
|
+
linktoFn: linktoExternal,
|
|
586
|
+
sectionName: SECTION_TYPE.Externals,
|
|
587
|
+
}),
|
|
588
|
+
|
|
589
|
+
[SECTION_TYPE.Events]: buildSidebarMembers({
|
|
590
|
+
itemHeading: "Events",
|
|
591
|
+
items: members.events,
|
|
592
|
+
itemsSeen: seen,
|
|
593
|
+
linktoFn: linkto,
|
|
594
|
+
sectionName: SECTION_TYPE.Events,
|
|
595
|
+
}),
|
|
596
|
+
|
|
597
|
+
[SECTION_TYPE.Namespaces]: buildSidebarMembers({
|
|
598
|
+
itemHeading: "Namespaces",
|
|
599
|
+
items: members.namespaces,
|
|
600
|
+
itemsSeen: seen,
|
|
601
|
+
linktoFn: linkto,
|
|
602
|
+
sectionName: SECTION_TYPE.Namespaces,
|
|
603
|
+
}),
|
|
604
|
+
|
|
605
|
+
[SECTION_TYPE.Mixins]: buildSidebarMembers({
|
|
606
|
+
itemHeading: "Mixins",
|
|
607
|
+
items: members.mixins,
|
|
608
|
+
itemsSeen: seen,
|
|
609
|
+
linktoFn: linkto,
|
|
610
|
+
sectionName: SECTION_TYPE.Mixins,
|
|
611
|
+
}),
|
|
612
|
+
|
|
613
|
+
[SECTION_TYPE.Tutorials]: buildSidebarMembers({
|
|
614
|
+
itemHeading: "Tutorials",
|
|
615
|
+
items: members.tutorials,
|
|
616
|
+
itemsSeen: seenTutorials,
|
|
617
|
+
linktoFn: linktoTutorial,
|
|
618
|
+
sectionName: SECTION_TYPE.Tutorials,
|
|
619
|
+
}),
|
|
620
|
+
|
|
621
|
+
[SECTION_TYPE.Interfaces]: buildSidebarMembers({
|
|
622
|
+
itemHeading: "Interfaces",
|
|
623
|
+
items: members.interfaces,
|
|
624
|
+
itemsSeen: seen,
|
|
625
|
+
linktoFn: linkto,
|
|
626
|
+
sectionName: SECTION_TYPE.Interfaces,
|
|
627
|
+
}),
|
|
628
|
+
|
|
629
|
+
[SECTION_TYPE.Global]: buildSidebarMembers({
|
|
630
|
+
itemHeading: i18n.t("global", "Global"),
|
|
631
|
+
items: members.globals,
|
|
632
|
+
itemsSeen: seenGlobal,
|
|
633
|
+
linktoFn: linkto,
|
|
634
|
+
sectionName: SECTION_TYPE.Global,
|
|
635
|
+
}),
|
|
636
|
+
};
|
|
637
|
+
|
|
638
|
+
sectionsOrder.forEach((section) => {
|
|
639
|
+
if (SECTION_TYPE[section] !== undefined) {
|
|
640
|
+
nav.sections.push(sections[section]);
|
|
641
|
+
} else {
|
|
642
|
+
const errorMsg = `While building nav. Section name: ${section} is not recognized.
|
|
643
|
+
Accepted sections are: ${defaultSections.join(", ")}
|
|
644
|
+
`;
|
|
645
|
+
|
|
646
|
+
throw new Error(errorMsg);
|
|
647
|
+
}
|
|
648
|
+
});
|
|
649
|
+
|
|
650
|
+
return nav;
|
|
651
|
+
}
|
|
652
|
+
|
|
653
|
+
/**
|
|
654
|
+
@param {TAFFY} taffyData See <http://taffydb.com/>.
|
|
655
|
+
@param {object} opts
|
|
656
|
+
@param {Tutorial} tutorials
|
|
657
|
+
*/
|
|
658
|
+
exports.publish = async function (taffyData, opts, tutorials) {
|
|
659
|
+
// Initialize i18n system
|
|
660
|
+
const language =
|
|
661
|
+
(opts && opts.theme_opts && opts.theme_opts.language) || "en";
|
|
662
|
+
i18n.init({ language });
|
|
663
|
+
|
|
664
|
+
let classes;
|
|
665
|
+
let conf;
|
|
666
|
+
let externals;
|
|
667
|
+
let files;
|
|
668
|
+
let fromDir;
|
|
669
|
+
let globalUrl;
|
|
670
|
+
let indexUrl;
|
|
671
|
+
let interfaces;
|
|
672
|
+
let members;
|
|
673
|
+
let mixins;
|
|
674
|
+
let modules;
|
|
675
|
+
let namespaces;
|
|
676
|
+
let outputSourceFiles;
|
|
677
|
+
let packageInfo;
|
|
678
|
+
let packages;
|
|
679
|
+
const sourceFilePaths = [];
|
|
680
|
+
let sourceFiles = {};
|
|
681
|
+
let staticFileFilter;
|
|
682
|
+
let staticFilePaths;
|
|
683
|
+
let staticFiles;
|
|
684
|
+
let staticFileScanner;
|
|
685
|
+
let templatePath;
|
|
686
|
+
|
|
687
|
+
data = taffyData;
|
|
688
|
+
|
|
689
|
+
conf = env.conf.templates || {};
|
|
690
|
+
conf.default = conf.default || {};
|
|
691
|
+
|
|
692
|
+
templatePath = path.normalize(opts.template);
|
|
693
|
+
view = new template.Template(path.join(templatePath, "tmpl"));
|
|
694
|
+
|
|
695
|
+
// claim some special filenames in advance, so the All-Powerful Overseer of Filename Uniqueness
|
|
696
|
+
// doesn't try to hand them out later
|
|
697
|
+
indexUrl = helper.getUniqueFilename("index");
|
|
698
|
+
// don't call registerLink() on this one! 'index' is also a valid longname
|
|
699
|
+
|
|
700
|
+
globalUrl = helper.getUniqueFilename("global");
|
|
701
|
+
helper.registerLink("global", globalUrl);
|
|
702
|
+
|
|
703
|
+
// set up templating
|
|
704
|
+
view.layout = conf.default.layoutFile
|
|
705
|
+
? path.resolve(conf.default.layoutFile)
|
|
706
|
+
: "layout.tmpl";
|
|
707
|
+
|
|
708
|
+
// set up tutorials for helper
|
|
709
|
+
helper.setTutorials(tutorials);
|
|
710
|
+
|
|
711
|
+
data = helper.prune(data);
|
|
712
|
+
|
|
713
|
+
// eslint-disable-next-line no-extra-boolean-cast, no-implicit-coercion
|
|
714
|
+
if (themeOpts.sort !== false) {
|
|
715
|
+
data.sort("longname, version, since");
|
|
716
|
+
}
|
|
717
|
+
|
|
718
|
+
helper.addEventListeners(data);
|
|
719
|
+
|
|
720
|
+
data().each((doclet) => {
|
|
721
|
+
let sourcePath;
|
|
722
|
+
|
|
723
|
+
doclet.attribs = "";
|
|
724
|
+
|
|
725
|
+
if (doclet.examples) {
|
|
726
|
+
doclet.examples = doclet.examples.map((example) => {
|
|
727
|
+
let caption;
|
|
728
|
+
let code;
|
|
729
|
+
|
|
730
|
+
if (
|
|
731
|
+
example.match(
|
|
732
|
+
/^\s*<caption>([\s\S]+?)<\/caption>(\s*[\n\r])([\s\S]+)$/i
|
|
733
|
+
)
|
|
734
|
+
) {
|
|
735
|
+
caption = RegExp.$1;
|
|
736
|
+
code = RegExp.$3;
|
|
737
|
+
}
|
|
738
|
+
|
|
739
|
+
return {
|
|
740
|
+
caption: caption || "",
|
|
741
|
+
code: code || example,
|
|
742
|
+
};
|
|
743
|
+
});
|
|
744
|
+
}
|
|
745
|
+
|
|
746
|
+
if (doclet.see) {
|
|
747
|
+
doclet.see.forEach(function (seeItem, i) {
|
|
748
|
+
doclet.see[i] = hashToLink(doclet, seeItem);
|
|
749
|
+
});
|
|
750
|
+
}
|
|
751
|
+
|
|
752
|
+
// build a list of source files
|
|
753
|
+
if (doclet.meta) {
|
|
754
|
+
sourcePath = getPathFromDoclet(doclet);
|
|
755
|
+
sourceFiles[sourcePath] = {
|
|
756
|
+
resolved: sourcePath,
|
|
757
|
+
shortened: null,
|
|
758
|
+
};
|
|
759
|
+
if (sourceFilePaths.indexOf(sourcePath) === -1) {
|
|
760
|
+
sourceFilePaths.push(sourcePath);
|
|
761
|
+
}
|
|
762
|
+
}
|
|
763
|
+
|
|
764
|
+
// added by clean-jsdoc-theme-dev.
|
|
765
|
+
// to process yields.
|
|
766
|
+
if (doclet.yields) {
|
|
767
|
+
doclet.yields = getProcessedYield(doclet.yields);
|
|
768
|
+
}
|
|
769
|
+
});
|
|
770
|
+
|
|
771
|
+
// update outdir if necessary, then create outdir
|
|
772
|
+
packageInfo = (find({ kind: "package" }) || [])[0];
|
|
773
|
+
if (packageInfo && packageInfo.name) {
|
|
774
|
+
outdir = path.join(outdir, packageInfo.name, packageInfo.version || "");
|
|
775
|
+
}
|
|
776
|
+
mkdirSync(outdir);
|
|
777
|
+
|
|
778
|
+
// copy external static folders
|
|
779
|
+
copyStaticFolder(themeOpts, outdir);
|
|
780
|
+
|
|
781
|
+
// copy the template's static files to outdir
|
|
782
|
+
fromDir = path.join(templatePath, "static");
|
|
783
|
+
staticFiles = lsSync(fromDir);
|
|
784
|
+
|
|
785
|
+
staticFiles.forEach((fileName) => {
|
|
786
|
+
const toPath = sourceToDestination(fromDir, fileName, outdir);
|
|
787
|
+
|
|
788
|
+
mkdirSync(path.dirname(toPath));
|
|
789
|
+
fs.copyFileSync(fileName, toPath);
|
|
790
|
+
});
|
|
791
|
+
|
|
792
|
+
// copy user-specified static files to outdir
|
|
793
|
+
if (conf.default.staticFiles) {
|
|
794
|
+
// The canonical property name is `include`. We accept `paths` for backwards compatibility
|
|
795
|
+
// with a bug in JSDoc 3.2.x.
|
|
796
|
+
staticFilePaths =
|
|
797
|
+
conf.default.staticFiles.include || conf.default.staticFiles.paths || [];
|
|
798
|
+
staticFileFilter = new (require("jsdoc/src/filter").Filter)(
|
|
799
|
+
conf.default.staticFiles
|
|
800
|
+
);
|
|
801
|
+
staticFileScanner = new (require("jsdoc/src/scanner").Scanner)();
|
|
802
|
+
|
|
803
|
+
staticFilePaths.forEach((filePath) => {
|
|
804
|
+
filePath = path.resolve(env.pwd, filePath);
|
|
805
|
+
const extraStaticFiles = staticFileScanner.scan(
|
|
806
|
+
[filePath],
|
|
807
|
+
10,
|
|
808
|
+
staticFileFilter
|
|
809
|
+
);
|
|
810
|
+
|
|
811
|
+
extraStaticFiles.forEach((fileName) => {
|
|
812
|
+
const toPath = sourceToDestination(filePath, fileName, outdir);
|
|
813
|
+
|
|
814
|
+
mkdirSync(path.dirname(toPath));
|
|
815
|
+
fs.copyFileSync(fileName, toPath);
|
|
816
|
+
});
|
|
817
|
+
});
|
|
818
|
+
}
|
|
819
|
+
|
|
820
|
+
if (sourceFilePaths.length) {
|
|
821
|
+
sourceFiles = shortenPaths(sourceFiles, path.commonPrefix(sourceFilePaths));
|
|
822
|
+
}
|
|
823
|
+
|
|
824
|
+
data().each(function (doclet) {
|
|
825
|
+
let docletPath;
|
|
826
|
+
const url = helper.createLink(doclet);
|
|
827
|
+
|
|
828
|
+
helper.registerLink(doclet.longname, url);
|
|
829
|
+
|
|
830
|
+
// add a shortened version of the full path
|
|
831
|
+
if (doclet.meta) {
|
|
832
|
+
docletPath = getPathFromDoclet(doclet);
|
|
833
|
+
docletPath = sourceFiles[docletPath].shortened;
|
|
834
|
+
if (docletPath) {
|
|
835
|
+
doclet.meta.shortpath = docletPath;
|
|
836
|
+
}
|
|
837
|
+
}
|
|
838
|
+
});
|
|
839
|
+
|
|
840
|
+
data().each(function (doclet) {
|
|
841
|
+
const url = helper.longnameToUrl[doclet.longname];
|
|
842
|
+
|
|
843
|
+
if (url.indexOf("#") > -1) {
|
|
844
|
+
doclet.id = helper.longnameToUrl[doclet.longname].split(/#/).pop();
|
|
845
|
+
} else {
|
|
846
|
+
doclet.id = doclet.name;
|
|
847
|
+
}
|
|
848
|
+
|
|
849
|
+
if (needsSignature(doclet)) {
|
|
850
|
+
addSignatureParams(doclet);
|
|
851
|
+
addSignatureReturns(doclet);
|
|
852
|
+
addAttribs(doclet);
|
|
853
|
+
}
|
|
854
|
+
});
|
|
855
|
+
|
|
856
|
+
// do this after the urls have all been generated
|
|
857
|
+
data().each((doclet) => {
|
|
858
|
+
doclet.ancestors = getAncestorLinks(doclet);
|
|
859
|
+
|
|
860
|
+
if (doclet.kind === "member") {
|
|
861
|
+
addSignatureTypes(doclet);
|
|
862
|
+
addAttribs(doclet);
|
|
863
|
+
}
|
|
864
|
+
|
|
865
|
+
if (doclet.kind === "constant") {
|
|
866
|
+
addSignatureTypes(doclet);
|
|
867
|
+
addAttribs(doclet);
|
|
868
|
+
doclet.kind = "member";
|
|
869
|
+
}
|
|
870
|
+
});
|
|
871
|
+
|
|
872
|
+
members = helper.getMembers(data);
|
|
873
|
+
members.tutorials = tutorials.children;
|
|
874
|
+
|
|
875
|
+
// output pretty-printed source files by default
|
|
876
|
+
outputSourceFiles = Boolean(
|
|
877
|
+
conf.default && conf.default.outputSourceFiles !== false
|
|
878
|
+
);
|
|
879
|
+
|
|
880
|
+
// add template helpers
|
|
881
|
+
view.find = find;
|
|
882
|
+
view.linkto = linkto;
|
|
883
|
+
view.resolveAuthorLinks = resolveAuthorLinks;
|
|
884
|
+
view.tutoriallink = tutoriallink;
|
|
885
|
+
view.htmlsafe = htmlsafe;
|
|
886
|
+
view.outputSourceFiles = outputSourceFiles;
|
|
887
|
+
view.footer = buildFooter(themeOpts);
|
|
888
|
+
view.displayModuleHeader = moduleHeader(themeOpts);
|
|
889
|
+
view.favicon = getFavicon(themeOpts);
|
|
890
|
+
view.dynamicStyle = createDynamicStyleSheet(themeOpts);
|
|
891
|
+
view.dynamicStyleSrc = returnPathOfStyleSrc(themeOpts);
|
|
892
|
+
view.dynamicScript = createDynamicsScripts(themeOpts);
|
|
893
|
+
view.dynamicScriptSrc = returnPathOfScriptScr(themeOpts);
|
|
894
|
+
view.includeScript = includeScript(themeOpts, outdir);
|
|
895
|
+
view.includeCss = includeCss(themeOpts, outdir);
|
|
896
|
+
view.meta = getMetaTagData(themeOpts);
|
|
897
|
+
view.theme = getTheme(themeOpts);
|
|
898
|
+
// Add i18n function to view
|
|
899
|
+
view.t = i18n.t;
|
|
900
|
+
view.currentLanguage = i18n.getCurrentLanguage();
|
|
901
|
+
|
|
902
|
+
// Make t function globally available in templates
|
|
903
|
+
global.t = i18n.t;
|
|
904
|
+
// once for all
|
|
905
|
+
view.sidebar = buildSidebar(members);
|
|
906
|
+
view.navbar = buildNavbar(themeOpts);
|
|
907
|
+
view.resizeable = resizeable(themeOpts);
|
|
908
|
+
view.codepen = codepen(themeOpts);
|
|
909
|
+
view.excludeInherited = Boolean(themeOpts.exclude_inherited);
|
|
910
|
+
view.baseURL = getBaseURL(themeOpts);
|
|
911
|
+
view.shouldRemoveScrollbarStyle = Boolean(
|
|
912
|
+
themeOpts.shouldRemoveScrollbarStyle
|
|
913
|
+
);
|
|
914
|
+
attachModuleSymbols(find({ longname: { left: "module:" } }), members.modules);
|
|
915
|
+
|
|
916
|
+
if (themeOpts.prefixModuleToSidebarItems_experimental) {
|
|
917
|
+
view.sidebar.sections.forEach((section, i) => {
|
|
918
|
+
view.sidebar.sections[i].items = section.items.map((item) => {
|
|
919
|
+
item.anchor = prefixModuleToItemAnchor(item);
|
|
920
|
+
|
|
921
|
+
return item;
|
|
922
|
+
});
|
|
923
|
+
});
|
|
924
|
+
}
|
|
925
|
+
|
|
926
|
+
// generate the pretty-printed source files first so other pages can link to them
|
|
927
|
+
if (outputSourceFiles) {
|
|
928
|
+
generateSourceFiles(sourceFiles, packageInfo, opts.encoding);
|
|
929
|
+
}
|
|
930
|
+
|
|
931
|
+
if (members.globals.length) {
|
|
932
|
+
await generate(
|
|
933
|
+
"Global",
|
|
934
|
+
[{ kind: "globalobj" }],
|
|
935
|
+
globalUrl,
|
|
936
|
+
true,
|
|
937
|
+
packageInfo
|
|
938
|
+
);
|
|
939
|
+
}
|
|
940
|
+
|
|
941
|
+
// index page displays information from package.json and lists files
|
|
942
|
+
files = find({ kind: "file" });
|
|
943
|
+
packages = find({ kind: "package" });
|
|
944
|
+
// added by clean-jsdoc-theme-devs
|
|
945
|
+
const homepageTitle = themeOpts.homepageTitle || "Home";
|
|
946
|
+
const includeFilesListInHomepage =
|
|
947
|
+
themeOpts.includeFilesListInHomepage || false;
|
|
948
|
+
|
|
949
|
+
console.log("🏠🏠🏠 GENERATING INDEX PAGE 🏠🏠🏠");
|
|
950
|
+
console.log("🏠 indexUrl:", indexUrl);
|
|
951
|
+
console.log("🏠 packages:", packages.length);
|
|
952
|
+
console.log("🏠 packageInfo for index:", JSON.stringify(packageInfo));
|
|
953
|
+
|
|
954
|
+
await generate(
|
|
955
|
+
homepageTitle,
|
|
956
|
+
packages
|
|
957
|
+
.concat([
|
|
958
|
+
{
|
|
959
|
+
kind: "mainpage",
|
|
960
|
+
readme: opts.readme,
|
|
961
|
+
longname: opts.mainpagetitle ? opts.mainpagetitle : "Main Page",
|
|
962
|
+
},
|
|
963
|
+
])
|
|
964
|
+
.concat(includeFilesListInHomepage ? files : []),
|
|
965
|
+
indexUrl,
|
|
966
|
+
true,
|
|
967
|
+
packageInfo
|
|
968
|
+
);
|
|
969
|
+
|
|
970
|
+
// set up the lists that we'll use to generate pages
|
|
971
|
+
classes = taffy(members.classes);
|
|
972
|
+
modules = taffy(members.modules);
|
|
973
|
+
namespaces = taffy(members.namespaces);
|
|
974
|
+
mixins = taffy(members.mixins);
|
|
975
|
+
externals = taffy(members.externals);
|
|
976
|
+
interfaces = taffy(members.interfaces);
|
|
977
|
+
|
|
978
|
+
Object.keys(helper.longnameToUrl).forEach(async function (longname) {
|
|
979
|
+
const myClasses = helper.find(classes, { longname: longname });
|
|
980
|
+
const myExternals = helper.find(externals, { longname: longname });
|
|
981
|
+
const myInterfaces = helper.find(interfaces, { longname: longname });
|
|
982
|
+
const myMixins = helper.find(mixins, { longname: longname });
|
|
983
|
+
const myModules = helper.find(modules, { longname: longname });
|
|
984
|
+
const myNamespaces = helper.find(namespaces, { longname: longname });
|
|
985
|
+
|
|
986
|
+
if (myModules.length) {
|
|
987
|
+
await generate(
|
|
988
|
+
`Module: ${myModules[0].name}`,
|
|
989
|
+
myModules,
|
|
990
|
+
helper.longnameToUrl[longname],
|
|
991
|
+
true,
|
|
992
|
+
packageInfo
|
|
993
|
+
);
|
|
994
|
+
}
|
|
995
|
+
|
|
996
|
+
if (myClasses.length) {
|
|
997
|
+
await generate(
|
|
998
|
+
`Class: ${myClasses[0].name}`,
|
|
999
|
+
myClasses,
|
|
1000
|
+
helper.longnameToUrl[longname],
|
|
1001
|
+
true,
|
|
1002
|
+
packageInfo
|
|
1003
|
+
);
|
|
1004
|
+
}
|
|
1005
|
+
|
|
1006
|
+
if (myNamespaces.length) {
|
|
1007
|
+
await generate(
|
|
1008
|
+
`Namespace: ${myNamespaces[0].name}`,
|
|
1009
|
+
myNamespaces,
|
|
1010
|
+
helper.longnameToUrl[longname],
|
|
1011
|
+
true,
|
|
1012
|
+
packageInfo
|
|
1013
|
+
);
|
|
1014
|
+
}
|
|
1015
|
+
|
|
1016
|
+
if (myMixins.length) {
|
|
1017
|
+
await generate(
|
|
1018
|
+
`Mixin: ${myMixins[0].name}`,
|
|
1019
|
+
myMixins,
|
|
1020
|
+
helper.longnameToUrl[longname],
|
|
1021
|
+
true,
|
|
1022
|
+
packageInfo
|
|
1023
|
+
);
|
|
1024
|
+
}
|
|
1025
|
+
|
|
1026
|
+
if (myExternals.length) {
|
|
1027
|
+
await generate(
|
|
1028
|
+
`External: ${myExternals[0].name}`,
|
|
1029
|
+
myExternals,
|
|
1030
|
+
helper.longnameToUrl[longname],
|
|
1031
|
+
true,
|
|
1032
|
+
packageInfo
|
|
1033
|
+
);
|
|
1034
|
+
}
|
|
1035
|
+
|
|
1036
|
+
if (myInterfaces.length) {
|
|
1037
|
+
await generate(
|
|
1038
|
+
`Interface: ${myInterfaces[0].name}`,
|
|
1039
|
+
myInterfaces,
|
|
1040
|
+
helper.longnameToUrl[longname],
|
|
1041
|
+
true,
|
|
1042
|
+
packageInfo
|
|
1043
|
+
);
|
|
1044
|
+
}
|
|
1045
|
+
});
|
|
1046
|
+
|
|
1047
|
+
// TODO: move the tutorial functions to templateHelper.js
|
|
1048
|
+
async function generateTutorial(title, tutorial, filename) {
|
|
1049
|
+
const tutorialData = {
|
|
1050
|
+
title: title,
|
|
1051
|
+
header: tutorial.title,
|
|
1052
|
+
content: tutorial.parse(),
|
|
1053
|
+
children: tutorial.children,
|
|
1054
|
+
filename,
|
|
1055
|
+
};
|
|
1056
|
+
|
|
1057
|
+
const tutorialPath = path.join(outdir, filename);
|
|
1058
|
+
let html = view.render("tutorial.tmpl", tutorialData);
|
|
1059
|
+
|
|
1060
|
+
// yes, you can use {@link} in tutorials too!
|
|
1061
|
+
html = helper.resolveLinks(html); // turn {@link foo} into <a href="foodoc.html">foo</a>
|
|
1062
|
+
|
|
1063
|
+
const minifiedHTML = await htmlMinify.minify(html, HTML_MINIFY_OPTIONS);
|
|
1064
|
+
|
|
1065
|
+
fs.writeFileSync(tutorialPath, minifiedHTML, "utf8");
|
|
1066
|
+
|
|
1067
|
+
// added by clean-jsdoc-theme-devs
|
|
1068
|
+
// adding support for tutorial
|
|
1069
|
+
if (!hasSearch) return;
|
|
1070
|
+
|
|
1071
|
+
try {
|
|
1072
|
+
const baseName = path.basename(tutorialPath);
|
|
1073
|
+
let body = /<body.*?>([\s\S]*)<\/body>/.exec(tutorialData.content);
|
|
1074
|
+
let description = "";
|
|
1075
|
+
|
|
1076
|
+
if (!Array.isArray(body)) {
|
|
1077
|
+
body = /<article.*?>([\s\S]*)<\/article>/.exec(tutorialData.content);
|
|
1078
|
+
}
|
|
1079
|
+
|
|
1080
|
+
if (Array.isArray(body) && typeof body[1] === "string") {
|
|
1081
|
+
description = body[1]
|
|
1082
|
+
// Replacing all html tags
|
|
1083
|
+
.replace(/(<([^>]+)>)/g, "")
|
|
1084
|
+
// Replacing all kind of line breaks
|
|
1085
|
+
.replace(/(\r\n|\n|\r)/gm, " ")
|
|
1086
|
+
// Replacing all multi spaces with single space
|
|
1087
|
+
.replace(/\s+/gm, " ")
|
|
1088
|
+
// Taking only first 100 characters
|
|
1089
|
+
.substring(0, 100);
|
|
1090
|
+
}
|
|
1091
|
+
|
|
1092
|
+
if (typeof baseName === "string" && baseName) {
|
|
1093
|
+
searchList.push({
|
|
1094
|
+
title: tutorialData.header,
|
|
1095
|
+
link: `<a href="${baseName}">${baseName}</a>`,
|
|
1096
|
+
description,
|
|
1097
|
+
});
|
|
1098
|
+
}
|
|
1099
|
+
} catch (error) {
|
|
1100
|
+
console.error(
|
|
1101
|
+
"There was some error while creating search array for tutorial."
|
|
1102
|
+
);
|
|
1103
|
+
console.error(error);
|
|
1104
|
+
}
|
|
1105
|
+
}
|
|
1106
|
+
|
|
1107
|
+
// tutorials can have only one parent so there is no risk for loops
|
|
1108
|
+
function saveChildren({ children }) {
|
|
1109
|
+
children.forEach(function (child) {
|
|
1110
|
+
generateTutorial(
|
|
1111
|
+
`Tutorial: ${child.title}`,
|
|
1112
|
+
child,
|
|
1113
|
+
helper.tutorialToUrl(child.name)
|
|
1114
|
+
);
|
|
1115
|
+
saveChildren(child);
|
|
1116
|
+
});
|
|
1117
|
+
}
|
|
1118
|
+
|
|
1119
|
+
saveChildren(tutorials);
|
|
1120
|
+
|
|
1121
|
+
// added by clean-jsdoc-theme-devs
|
|
1122
|
+
// output search file if search
|
|
1123
|
+
if (hasSearch) {
|
|
1124
|
+
buildSearchListForData();
|
|
1125
|
+
mkdirSync(path.join(outdir, "data"));
|
|
1126
|
+
fs.writeFileSync(
|
|
1127
|
+
path.join(outdir, "data", "search.json"),
|
|
1128
|
+
JSON.stringify({
|
|
1129
|
+
list: searchList,
|
|
1130
|
+
})
|
|
1131
|
+
);
|
|
1132
|
+
}
|
|
1133
|
+
};
|