Clean lint from jsdoc config

This commit is contained in:
Tim Schaub
2018-04-19 17:27:02 -06:00
parent d17f0d98a0
commit a09f7fb3bb
10 changed files with 448 additions and 442 deletions

View File

@@ -1,3 +1,4 @@
examples/Jugl.js examples/Jugl.js
examples/resources/ examples/resources/
build/package/**/*webgl* build/package/**/*webgl*
config/jsdoc/api/template/static/scripts/

View File

@@ -1,5 +1,6 @@
/** /**
* Define an @api tag * Define an @api tag
* @param {Object} dictionary The tag dictionary.
*/ */
exports.defineTags = function(dictionary) { exports.defineTags = function(dictionary) {
dictionary.defineTag('api', { dictionary.defineTag('api', {
@@ -8,32 +9,31 @@ exports.defineTags = function(dictionary) {
canHaveName: false, canHaveName: false,
onTagged: function(doclet, tag) { onTagged: function(doclet, tag) {
includeTypes(doclet); includeTypes(doclet);
doclet.stability = "stable"; doclet.stability = 'stable';
} }
}); });
}; };
/* /*
* Based on @api annotations, and assuming that items with no @api annotation * Based on @api annotations, and assuming that items with no @api annotation
* should not be documented, this plugin removes undocumented symbols * should not be documented, this plugin removes undocumented symbols
* from the documentation. * from the documentation.
*/ */
var api = []; const api = [];
var classes = {}; const classes = {};
var types = {}; const types = {};
function hasApiMembers(doclet) { function hasApiMembers(doclet) {
return doclet.longname.split('#')[0] == this.longname; return doclet.longname.split('#')[0] == this.longname;
} }
function includeAugments(doclet) { function includeAugments(doclet) {
var augments = doclet.augments; const augments = doclet.augments;
if (augments) { if (augments) {
var cls; let cls;
for (var i = augments.length - 1; i >= 0; --i) { for (let i = augments.length - 1; i >= 0; --i) {
cls = classes[augments[i]]; cls = classes[augments[i]];
if (cls) { if (cls) {
includeAugments(cls); includeAugments(cls);
@@ -68,7 +68,7 @@ function includeAugments(doclet) {
function extractTypes(item) { function extractTypes(item) {
item.type.names.forEach(function(type) { item.type.names.forEach(function(type) {
var match = type.match(/^(.*<)?([^>]*)>?$/); const match = type.match(/^(.*<)?([^>]*)>?$/);
if (match) { if (match) {
types[match[2]] = true; types[match[2]] = true;
} }
@@ -94,7 +94,7 @@ function includeTypes(doclet) {
exports.handlers = { exports.handlers = {
newDoclet: function(e) { newDoclet: function(e) {
var doclet = e.doclet; const doclet = e.doclet;
// Keep track of api items - needed in parseComplete to determine classes // Keep track of api items - needed in parseComplete to determine classes
// with api members. // with api members.
if (doclet.meta.filename == 'olx.js' && doclet.kind == 'typedef') { if (doclet.meta.filename == 'olx.js' && doclet.kind == 'typedef') {
@@ -114,9 +114,9 @@ exports.handlers = {
}, },
parseComplete: function(e) { parseComplete: function(e) {
var doclets = e.doclets; const doclets = e.doclets;
for (var i = doclets.length - 1; i >= 0; --i) { for (let i = doclets.length - 1; i >= 0; --i) {
var doclet = doclets[i]; const doclet = doclets[i];
if (doclet.stability || doclet.namespace_) { if (doclet.stability || doclet.namespace_) {
if (doclet.kind == 'class') { if (doclet.kind == 'class') {
includeAugments(doclet); includeAugments(doclet);

View File

@@ -1,11 +1,11 @@
var events = {}; const events = {};
var classes = {}; const classes = {};
exports.handlers = { exports.handlers = {
newDoclet: function(e) { newDoclet: function(e) {
var doclet = e.doclet; const doclet = e.doclet;
var cls; let cls;
if (doclet.kind == 'event') { if (doclet.kind == 'event') {
cls = doclet.longname.split('#')[0]; cls = doclet.longname.split('#')[0];
if (!(cls in events)) { if (!(cls in events)) {
@@ -18,8 +18,8 @@ exports.handlers = {
}, },
parseComplete: function(e) { parseComplete: function(e) {
var doclets = e.doclets; const doclets = e.doclets;
var doclet, i, ii, j, jj, event, fires; let doclet, i, ii, j, jj, event, fires;
for (i = 0, ii = doclets.length - 1; i < ii; ++i) { for (i = 0, ii = doclets.length - 1; i < ii; ++i) {
doclet = doclets[i]; doclet = doclets[i];
if (doclet.fires) { if (doclet.fires) {
@@ -28,7 +28,7 @@ exports.handlers = {
for (j = 0, jj = doclet.fires.length; j < jj; ++j) { for (j = 0, jj = doclet.fires.length; j < jj; ++j) {
event = doclet.fires[j].replace('event:', ''); event = doclet.fires[j].replace('event:', '');
if (events[event]) { if (events[event]) {
fires.push.apply(fires, events[event]); fires.push.apply(fires, events[event]);
} else { } else {
fires.push(doclet.fires[j]); fires.push(doclet.fires[j]);
} }

View File

@@ -19,16 +19,16 @@ exports.defineTags = function(dictionary) {
}; };
var lookup = {}; const lookup = {};
var incompleteByClass = {}; const incompleteByClass = {};
var keepKeys = ['comment', 'meta', 'name', 'memberof', 'longname', 'augment', const keepKeys = ['comment', 'meta', 'name', 'memberof', 'longname', 'augment',
'stability']; 'stability'];
exports.handlers = { exports.handlers = {
newDoclet: function(e) { newDoclet: function(e) {
var doclet = e.doclet; const doclet = e.doclet;
var incompletes; let incompletes;
if (!(doclet.longname in lookup)) { if (!(doclet.longname in lookup)) {
lookup[doclet.longname] = []; lookup[doclet.longname] = [];
} }
@@ -45,9 +45,9 @@ exports.handlers = {
}, },
parseComplete: function(e) { parseComplete: function(e) {
var ancestors, candidate, candidates, doclet, i, j, k, l, key; let ancestors, candidate, candidates, doclet, i, j, k, l, key;
var incompleteDoclet, stability, incomplete, incompletes; let incompleteDoclet, stability, incomplete, incompletes;
var doclets = e.doclets; const doclets = e.doclets;
for (i = doclets.length - 1; i >= 0; --i) { for (i = doclets.length - 1; i >= 0; --i) {
doclet = doclets[i]; doclet = doclets[i];
if (doclet.augments) { if (doclet.augments) {

View File

@@ -1,25 +1,25 @@
var classes = {}; const classes = {};
var observables = {}; const observables = {};
exports.handlers = { exports.handlers = {
newDoclet: function(e) { newDoclet: function(e) {
var doclet = e.doclet; const doclet = e.doclet;
if (doclet.kind == 'class') { if (doclet.kind == 'class') {
classes[doclet.longname] = doclet; classes[doclet.longname] = doclet;
} }
}, },
parseComplete: function(e) { parseComplete: function(e) {
var doclets = e.doclets; const doclets = e.doclets;
var cls, doclet, event, i, ii, observable; let cls, doclet, event, i, ii, observable;
for (i = 0, ii = doclets.length - 1; i < ii; ++i) { for (i = 0, ii = doclets.length - 1; i < ii; ++i) {
doclet = doclets[i]; doclet = doclets[i];
cls = classes[doclet.longname.split('#')[0]]; cls = classes[doclet.longname.split('#')[0]];
if (typeof doclet.observable == 'string' && cls) { if (typeof doclet.observable == 'string' && cls) {
var name = doclet.name.replace(/^[sg]et/, ''); let name = doclet.name.replace(/^[sg]et/, '');
name = name.substr(0, 1).toLowerCase() + name.substr(1); name = name.substr(0, 1).toLowerCase() + name.substr(1);
var key = doclet.longname.split('#')[0] + '#' + name; const key = doclet.longname.split('#')[0] + '#' + name;
doclet.observable = key; doclet.observable = key;
if (!observables[key]) { if (!observables[key]) {
observables[key] = {}; observables[key] = {};
@@ -27,7 +27,7 @@ exports.handlers = {
observable = observables[key]; observable = observables[key];
observable.name = name; observable.name = name;
observable.readonly = typeof observable.readonly == 'boolean' ? observable.readonly = typeof observable.readonly == 'boolean' ?
observable.readonly : true; observable.readonly : true;
if (doclet.name.indexOf('get') === 0) { if (doclet.name.indexOf('get') === 0) {
observable.type = doclet.returns[0].type; observable.type = doclet.returns[0].type;
observable.description = doclet.returns[0].description; observable.description = doclet.returns[0].description;

View File

@@ -3,19 +3,19 @@
* Changes @enum annotations into @typedef. * Changes @enum annotations into @typedef.
*/ */
var lastOlxTypedef = null; let lastOlxTypedef = null;
var olxTypes = {}; const olxTypes = {};
// names of the olx typenames // names of the olx typenames
var olxTypeNames = []; const olxTypeNames = [];
// types that are undefined or typedefs containing undefined // types that are undefined or typedefs containing undefined
var undefinedLikes = null; let undefinedLikes = null;
function addSubparams(params) { function addSubparams(params) {
for (var j = 0, jj = params.length; j < jj; ++j) { for (let j = 0, jj = params.length; j < jj; ++j) {
var param = params[j]; const param = params[j];
var types = param.type.names; const types = param.type.names;
for (var k = 0, kk = types.length; k < kk; ++k) { for (let k = 0, kk = types.length; k < kk; ++k) {
var name = types[k]; const name = types[k];
if (name in olxTypes) { if (name in olxTypes) {
param.subparams = olxTypes[name]; param.subparams = olxTypes[name];
// TODO addSubparams(param.subparams); // TODO addSubparams(param.subparams);
@@ -30,20 +30,22 @@ function addSubparams(params) {
/** /**
* Changes the description of the param, if it is found to be a required * Changes the description of the param, if it is found to be a required
* option of an olxTypeName. * option of an olxTypeName.
* @param {Object} doclet The doclet.
* @returns {Object} The modified doclet.
*/ */
function markRequiredIfNeeded(doclet){ function markRequiredIfNeeded(doclet) {
var memberof = doclet.memberof; const memberof = doclet.memberof;
// only check doclets that belong to an olxTypeName // only check doclets that belong to an olxTypeName
if (!memberof || olxTypeNames.indexOf(memberof) == -1) { if (!memberof || olxTypeNames.indexOf(memberof) == -1) {
return doclet; return doclet;
} }
var types = doclet.type.names; const types = doclet.type.names;
var isRequiredParam = true; let isRequiredParam = true;
// iterate over all types that are like-undefined (see above for explanation) // iterate over all types that are like-undefined (see above for explanation)
for (var idx = undefinedLikes.length - 1; idx >= 0; idx--) { for (let idx = undefinedLikes.length - 1; idx >= 0; idx--) {
var undefinedLike = undefinedLikes[idx]; const undefinedLike = undefinedLikes[idx];
// … if the current types contains a type that is undefined-like, // … if the current types contains a type that is undefined-like,
// it is not required. // it is not required.
if (types.indexOf(undefinedLike) != -1) { if (types.indexOf(undefinedLike) != -1) {
@@ -52,9 +54,9 @@ function markRequiredIfNeeded(doclet){
} }
if (isRequiredParam) { if (isRequiredParam) {
var reqSnippet = '<span class="required-option">Required.</span></p>'; const reqSnippet = '<span class="required-option">Required.</span></p>';
var endsWithP = /<\/p>$/i; const endsWithP = /<\/p>$/i;
var description = doclet.description; let description = doclet.description;
if (description && endsWithP.test(description)) { if (description && endsWithP.test(description)) {
description = description.replace(endsWithP, ' ' + reqSnippet); description = description.replace(endsWithP, ' ' + reqSnippet);
} else if (doclet.description === undefined) { } else if (doclet.description === undefined) {
@@ -69,13 +71,14 @@ function markRequiredIfNeeded(doclet){
* Iterates over all doclets and finds the names of types that contain * Iterates over all doclets and finds the names of types that contain
* undefined. Stores the names in the global variable undefinedLikes, so * undefined. Stores the names in the global variable undefinedLikes, so
* that e.g. markRequiredIfNeeded can use these. * that e.g. markRequiredIfNeeded can use these.
* @param {Array} doclets The doclets.
*/ */
function findTypesLikeUndefined(doclets) { function findTypesLikeUndefined(doclets) {
undefinedLikes = ['undefined']; // include type 'undefined' explicitly undefinedLikes = ['undefined']; // include type 'undefined' explicitly
for (var i = doclets.length - 1; i >= 0; --i) { for (let i = doclets.length - 1; i >= 0; --i) {
var doclet = doclets[i]; const doclet = doclets[i];
if(doclet.kind === 'typedef') { if (doclet.kind === 'typedef') {
var types = doclet.type.names; const types = doclet.type.names;
if (types.indexOf('undefined') !== -1) { if (types.indexOf('undefined') !== -1) {
// the typedef contains 'undefined', so it self is undefinedLike. // the typedef contains 'undefined', so it self is undefinedLike.
undefinedLikes.push(doclet.longname); undefinedLikes.push(doclet.longname);
@@ -87,7 +90,7 @@ function findTypesLikeUndefined(doclets) {
exports.handlers = { exports.handlers = {
newDoclet: function(e) { newDoclet: function(e) {
var doclet = e.doclet; const doclet = e.doclet;
if (doclet.meta.filename == 'olx.js') { if (doclet.meta.filename == 'olx.js') {
if (doclet.kind == 'typedef') { if (doclet.kind == 'typedef') {
lastOlxTypedef = doclet; lastOlxTypedef = doclet;
@@ -108,11 +111,11 @@ exports.handlers = {
}, },
parseComplete: function(e) { parseComplete: function(e) {
var doclets = e.doclets; const doclets = e.doclets;
findTypesLikeUndefined(doclets); findTypesLikeUndefined(doclets);
for (var i = doclets.length - 1; i >= 0; --i) { for (let i = doclets.length - 1; i >= 0; --i) {
var doclet = doclets[i]; const doclet = doclets[i];
var params = doclet.params; const params = doclet.params;
if (params) { if (params) {
addSubparams(params); addSubparams(params);
} }

View File

@@ -1,152 +1,152 @@
/*global env: true */ /*global env: true */
var template = require('jsdoc/lib/jsdoc/template'), const template = require('jsdoc/lib/jsdoc/template');
fs = require('jsdoc/lib/jsdoc/fs'), const fs = require('jsdoc/lib/jsdoc/fs');
path = require('jsdoc/lib/jsdoc/path'), const path = require('jsdoc/lib/jsdoc/path');
taffy = require('taffydb').taffy, const taffy = require('taffydb').taffy;
handle = require('jsdoc/lib/jsdoc/util/error').handle, const handle = require('jsdoc/lib/jsdoc/util/error').handle;
helper = require('jsdoc/lib/jsdoc/util/templateHelper'), const helper = require('jsdoc/lib/jsdoc/util/templateHelper');
_ = require('underscore'), const _ = require('underscore');
htmlsafe = helper.htmlsafe, const htmlsafe = helper.htmlsafe;
linkto = helper.linkto, const linkto = helper.linkto;
resolveAuthorLinks = helper.resolveAuthorLinks, const resolveAuthorLinks = helper.resolveAuthorLinks;
scopeToPunc = helper.scopeToPunc, const hasOwnProp = Object.prototype.hasOwnProperty;
hasOwnProp = Object.prototype.hasOwnProperty, const outdir = env.opts.destination;
data,
view, let view;
outdir = env.opts.destination; let data;
function find(spec) { function find(spec) {
return helper.find(data, spec); return helper.find(data, spec);
} }
function tutoriallink(tutorial) { function tutoriallink(tutorial) {
return helper.toTutorial(tutorial, null, { tag: 'em', classname: 'disabled', prefix: 'Tutorial: ' }); return helper.toTutorial(tutorial, null, {tag: 'em', classname: 'disabled', prefix: 'Tutorial: '});
} }
function getAncestorLinks(doclet) { function getAncestorLinks(doclet) {
return helper.getAncestorLinks(data, doclet); return helper.getAncestorLinks(data, doclet);
} }
function hashToLink(doclet, hash) { function hashToLink(doclet, hash) {
if ( !/^(#.+)/.test(hash) ) { return hash; } if (!/^(#.+)/.test(hash)) {
return hash;
}
var url = helper.createLink(doclet); let url = helper.createLink(doclet);
url = url.replace(/(#.+|$)/, hash); url = url.replace(/(#.+|$)/, hash);
return '<a href="' + url + '">' + hash + '</a>'; return '<a href="' + url + '">' + hash + '</a>';
} }
function needsSignature(doclet) { function needsSignature(doclet) {
var needsSig = false; let needsSig = false;
// function and class definitions always get a signature // function and class definitions always get a signature
if (doclet.kind === 'function' || doclet.kind === 'class') { if (doclet.kind === 'function' || doclet.kind === 'class') {
needsSig = true; needsSig = true;
} } else if (doclet.kind === 'typedef' && doclet.type && doclet.type.names &&
doclet.type.names.length) {
// typedefs that contain functions get a signature, too // typedefs that contain functions get a signature, too
else if (doclet.kind === 'typedef' && doclet.type && doclet.type.names && for (let i = 0, l = doclet.type.names.length; i < l; i++) {
doclet.type.names.length) { if (doclet.type.names[i].toLowerCase() === 'function') {
for (var i = 0, l = doclet.type.names.length; i < l; i++) { needsSig = true;
if (doclet.type.names[i].toLowerCase() === 'function') { break;
needsSig = true; }
break;
}
}
} }
}
return needsSig; return needsSig;
} }
function addSignatureParams(f) { function addSignatureParams(f) {
var params = helper.getSignatureParams(f, 'optional'); const params = helper.getSignatureParams(f, 'optional');
f.signature = (f.signature || '') + '('+params.join(', ')+')'; f.signature = (f.signature || '') + '(' + params.join(', ') + ')';
} }
function addSignatureReturns(f) { function addSignatureReturns(f) {
var returnTypes = helper.getSignatureReturns(f); const returnTypes = helper.getSignatureReturns(f);
f.signature = '<span class="signature">'+(f.signature || '') + '</span>'; f.signature = '<span class="signature">' + (f.signature || '') + '</span>';
if (returnTypes.length) { if (returnTypes.length) {
f.signature += '<span class="glyphicon glyphicon-circle-arrow-right"></span><span class="type-signature returnType">'+(returnTypes.length ? '{'+returnTypes.join('|')+'}' : '')+'</span>'; f.signature += '<span class="glyphicon glyphicon-circle-arrow-right"></span><span class="type-signature returnType">' + (returnTypes.length ? '{' + returnTypes.join('|') + '}' : '') + '</span>';
} }
} }
function addSignatureTypes(f) { function addSignatureTypes(f) {
var types = helper.getSignatureTypes(f); const types = helper.getSignatureTypes(f);
f.signature = (f.signature || '') + '<span class="type-signature">'+(types.length? ' :'+types.join('|') : '')+' </span>'; f.signature = (f.signature || '') + '<span class="type-signature">' + (types.length ? ' :' + types.join('|') : '') + ' </span>';
} }
function shortenPaths(files, commonPrefix) { function shortenPaths(files, commonPrefix) {
// always use forward slashes // always use forward slashes
var regexp = new RegExp('\\\\', 'g'); const regexp = new RegExp('\\\\', 'g');
Object.keys(files).forEach(function(file) { Object.keys(files).forEach(function(file) {
files[file].shortened = files[file].resolved.replace(commonPrefix, '') files[file].shortened = files[file].resolved.replace(commonPrefix, '')
.replace(regexp, '/'); .replace(regexp, '/');
}); });
return files; return files;
} }
function resolveSourcePath(filepath) { function resolveSourcePath(filepath) {
return path.resolve(process.cwd(), filepath); return path.resolve(process.cwd(), filepath);
} }
function getPathFromDoclet(doclet) { function getPathFromDoclet(doclet) {
if (!doclet.meta) { if (!doclet.meta) {
return; return;
} }
var filepath = doclet.meta.path && doclet.meta.path !== 'null' ? const filepath = doclet.meta.path && doclet.meta.path !== 'null' ?
doclet.meta.path + '/' + doclet.meta.filename.split(/[\/\\]/).pop() : doclet.meta.path + '/' + doclet.meta.filename.split(/[\/\\]/).pop() :
doclet.meta.filename; doclet.meta.filename;
return filepath; return filepath;
} }
function generate(title, docs, filename, resolveLinks) { function generate(title, docs, filename, resolveLinks) {
resolveLinks = resolveLinks === false ? false : true; resolveLinks = resolveLinks === false ? false : true;
var docData = { const docData = {
filename: filename, filename: filename,
title: title, title: title,
docs: docs, docs: docs,
packageInfo: ( find({kind: 'package'}) || [] ) [0] packageInfo: (find({kind: 'package'}) || []) [0]
}; };
var outpath = path.join(outdir, filename), const outpath = path.join(outdir, filename);
html = view.render('container.tmpl', docData); let html = view.render('container.tmpl', docData);
if (resolveLinks) { if (resolveLinks) {
html = helper.resolveLinks(html); // turn {@link foo} into <a href="foodoc.html">foo</a> html = helper.resolveLinks(html); // turn {@link foo} into <a href="foodoc.html">foo</a>
} }
fs.writeFileSync(outpath, html, 'utf8'); fs.writeFileSync(outpath, html, 'utf8');
} }
function generateSourceFiles(sourceFiles) { function generateSourceFiles(sourceFiles) {
Object.keys(sourceFiles).forEach(function(file) { Object.keys(sourceFiles).forEach(function(file) {
var source; let source;
// links are keyed to the shortened path in each doclet's `meta.filename` property // links are keyed to the shortened path in each doclet's `meta.filename` property
var sourceOutfile = helper.getUniqueFilename(sourceFiles[file].shortened); const sourceOutfile = helper.getUniqueFilename(sourceFiles[file].shortened);
helper.registerLink(sourceFiles[file].shortened, sourceOutfile); helper.registerLink(sourceFiles[file].shortened, sourceOutfile);
try { try {
source = { source = {
kind: 'source', kind: 'source',
code: helper.htmlsafe( fs.readFileSync(sourceFiles[file].resolved, 'utf8') ) code: helper.htmlsafe(fs.readFileSync(sourceFiles[file].resolved, 'utf8'))
}; };
} } catch (e) {
catch(e) { handle(e);
handle(e); }
}
generate('Source: ' + sourceFiles[file].shortened, [source], sourceOutfile, generate('Source: ' + sourceFiles[file].shortened, [source], sourceOutfile,
false); false);
}); });
} }
/** /**
@@ -161,346 +161,348 @@ function generateSourceFiles(sourceFiles) {
* @param {Array.<module:jsdoc/doclet.Doclet>} modules - The array of module doclets to search. * @param {Array.<module:jsdoc/doclet.Doclet>} modules - The array of module doclets to search.
*/ */
function attachModuleSymbols(doclets, modules) { function attachModuleSymbols(doclets, modules) {
var symbols = {}; const symbols = {};
// build a lookup table // build a lookup table
doclets.forEach(function(symbol) { doclets.forEach(function(symbol) {
symbols[symbol.longname] = symbol; symbols[symbol.longname] = symbol;
}); });
return modules.map(function(module) { modules.forEach(function(module) {
if (symbols[module.longname]) { if (symbols[module.longname]) {
module.module = symbols[module.longname]; module.module = symbols[module.longname];
module.module.name = module.module.name.replace('module:', 'require("') + '")'; module.module.name = module.module.name.replace('module:', 'require("') + '")';
} }
}); });
} }
/** /**
* Create the navigation sidebar. * Create the navigation sidebar.
* @param {object} members The members that will be used to create the sidebar. * @param {object} members The members that will be used to create the sidebar.
* @param {array<object>} members.classes * @param {Array<Object>} members.classes Classes.
* @param {array<object>} members.externals * @param {Array<Object>} members.externals Externals.
* @param {array<object>} members.globals * @param {Array<Object>} members.globals Globals.
* @param {array<object>} members.mixins * @param {Array<Object>} members.mixins Mixins.
* @param {array<object>} members.modules * @param {Array<Object>} members.modules Modules.
* @param {array<object>} members.namespaces * @param {Array<Object>} members.namespaces Namespaces.
* @param {array<object>} members.tutorials * @param {Array<Object>} members.tutorials Tutorials.
* @param {array<object>} members.events * @param {Array<Object>} members.events Events.
* @return {string} The HTML for the navigation sidebar. * @return {string} The HTML for the navigation sidebar.
*/ */
function buildNav(members) { function buildNav(members) {
var nav = []; const nav = [];
// merge namespaces and classes, then sort // merge namespaces and classes, then sort
var merged = members.namespaces.concat(members.classes); const merged = members.namespaces.concat(members.classes);
merged.sort(function (a, b) { merged.sort(function(a, b) {
if (a.longname > b.longname) if (a.longname > b.longname) {
return 1; return 1;
if (a.longname < b.longname) }
return -1; if (a.longname < b.longname) {
return 0; return -1;
}); }
_.each(merged, function (v) { return 0;
// exclude 'olx' and interfaces from sidebar });
if (v.longname.indexOf('olx') !== 0 && v.interface !== true) { _.each(merged, function(v) {
if (v.kind == 'namespace') { // exclude 'olx' and interfaces from sidebar
nav.push({ if (v.longname.indexOf('olx') !== 0 && v.interface !== true) {
type: 'namespace', if (v.kind == 'namespace') {
longname: v.longname, nav.push({
name: v.name, type: 'namespace',
members: find({ longname: v.longname,
kind: 'member', name: v.name,
memberof: v.longname members: find({
}), kind: 'member',
methods: find({ memberof: v.longname
kind: 'function', }),
memberof: v.longname methods: find({
}), kind: 'function',
typedefs: find({ memberof: v.longname
kind: 'typedef', }),
memberof: v.longname typedefs: find({
}), kind: 'typedef',
events: find({ memberof: v.longname
kind: 'event', }),
memberof: v.longname events: find({
}) kind: 'event',
}); memberof: v.longname
} })
if (v.kind == 'class') { });
nav.push({
type: 'class',
longname: v.longname,
name: v.name,
members: find({
kind: 'member',
memberof: v.longname
}),
methods: find({
kind: 'function',
memberof: v.longname
}),
typedefs: find({
kind: 'typedef',
memberof: v.longname
}),
fires: v.fires,
events: find({
kind: 'event',
memberof: v.longname
})
});
}
} }
}); if (v.kind == 'class') {
return nav; nav.push({
type: 'class',
longname: v.longname,
name: v.name,
members: find({
kind: 'member',
memberof: v.longname
}),
methods: find({
kind: 'function',
memberof: v.longname
}),
typedefs: find({
kind: 'typedef',
memberof: v.longname
}),
fires: v.fires,
events: find({
kind: 'event',
memberof: v.longname
})
});
}
}
});
return nav;
} }
/** /**
@param {TAFFY} taffyData See <http://taffydb.com/>. * @param {Object} taffyData See <http://taffydb.com/>.
@param {object} opts * @param {Object} opts Options.
@param {Tutorial} tutorials * @param {Object} tutorials Tutorials.
*/ */
exports.publish = function(taffyData, opts, tutorials) { exports.publish = function(taffyData, opts, tutorials) {
data = taffyData; data = taffyData;
var conf = env.conf.templates || {}; const conf = env.conf.templates || {};
conf['default'] = conf['default'] || {}; conf['default'] = conf['default'] || {};
var templatePath = opts.template; const templatePath = opts.template;
view = new template.Template(templatePath + '/tmpl'); view = new template.Template(templatePath + '/tmpl');
// claim some special filenames in advance, so the All-Powerful Overseer of Filename Uniqueness // claim some special filenames in advance, so the All-Powerful Overseer of Filename Uniqueness
// doesn't try to hand them out later // doesn't try to hand them out later
var indexUrl = helper.getUniqueFilename('index'); const indexUrl = helper.getUniqueFilename('index');
// don't call registerLink() on this one! 'index' is also a valid longname // don't call registerLink() on this one! 'index' is also a valid longname
var globalUrl = helper.getUniqueFilename('global'); const globalUrl = helper.getUniqueFilename('global');
helper.registerLink('global', globalUrl); helper.registerLink('global', globalUrl);
// set up templating // set up templating
view.layout = 'layout.tmpl'; view.layout = 'layout.tmpl';
// set up tutorials for helper // set up tutorials for helper
helper.setTutorials(tutorials); helper.setTutorials(tutorials);
data = helper.prune(data); data = helper.prune(data);
data.sort('longname, version, since'); data.sort('longname, version, since');
helper.addEventListeners(data); helper.addEventListeners(data);
var sourceFiles = {}; let sourceFiles = {};
var sourceFilePaths = []; const sourceFilePaths = [];
data().each(function(doclet) { data().each(function(doclet) {
doclet.attribs = ''; doclet.attribs = '';
if (doclet.examples) { if (doclet.examples) {
doclet.examples = doclet.examples.map(function(example) { doclet.examples = doclet.examples.map(function(example) {
var caption, code; let caption, code;
if (example.match(/^\s*<caption>([\s\S]+?)<\/caption>(\s*[\n\r])([\s\S]+)$/i)) { if (example.match(/^\s*<caption>([\s\S]+?)<\/caption>(\s*[\n\r])([\s\S]+)$/i)) {
caption = RegExp.$1; caption = RegExp.$1;
code = RegExp.$3; code = RegExp.$3;
}
return {
caption: caption || '',
code: code || example
};
});
}
if (doclet.see) {
doclet.see.forEach(function(seeItem, i) {
doclet.see[i] = hashToLink(doclet, seeItem);
});
} }
// build a list of source files return {
var sourcePath; caption: caption || '',
var resolvedSourcePath; code: code || example
if (doclet.meta) { };
sourcePath = getPathFromDoclet(doclet); });
resolvedSourcePath = resolveSourcePath(sourcePath); }
sourceFiles[sourcePath] = { if (doclet.see) {
resolved: resolvedSourcePath, doclet.see.forEach(function(seeItem, i) {
shortened: null doclet.see[i] = hashToLink(doclet, seeItem);
}; });
sourceFilePaths.push(resolvedSourcePath); }
}
});
fs.mkPath(outdir); // build a list of source files
let sourcePath;
let resolvedSourcePath;
if (doclet.meta) {
sourcePath = getPathFromDoclet(doclet);
resolvedSourcePath = resolveSourcePath(sourcePath);
sourceFiles[sourcePath] = {
resolved: resolvedSourcePath,
shortened: null
};
sourceFilePaths.push(resolvedSourcePath);
}
});
// copy the template's static files to outdir fs.mkPath(outdir);
var fromDir = path.join(templatePath, 'static');
var staticFiles = fs.ls(fromDir, 3);
staticFiles.forEach(function(fileName) { // copy the template's static files to outdir
var toDir = fs.toDir( fileName.replace(fromDir, outdir) ); const fromDir = path.join(templatePath, 'static');
const staticFiles = fs.ls(fromDir, 3);
staticFiles.forEach(function(fileName) {
const toDir = fs.toDir(fileName.replace(fromDir, outdir));
fs.mkPath(toDir);
fs.copyFileSync(fileName, toDir);
});
// copy user-specified static files to outdir
let staticFilePaths;
let staticFileFilter;
let staticFileScanner;
if (conf['default'].staticFiles) {
staticFilePaths = conf['default'].staticFiles.paths || [];
staticFileFilter = new (require('jsdoc/lib/jsdoc/src/filter')).Filter(conf['default'].staticFiles);
staticFileScanner = new (require('jsdoc/lib/jsdoc/src/scanner')).Scanner();
staticFilePaths.forEach(function(filePath) {
const extraStaticFiles = staticFileScanner.scan([filePath], 10, staticFileFilter);
extraStaticFiles.forEach(function(fileName) {
const sourcePath = fs.statSync(filePath).isDirectory() ? filePath :
path.dirname(filePath);
const toDir = fs.toDir(fileName.replace(sourcePath, outdir));
fs.mkPath(toDir); fs.mkPath(toDir);
fs.copyFileSync(fileName, toDir); fs.copyFileSync(fileName, toDir);
});
}); });
}
// copy user-specified static files to outdir if (sourceFilePaths.length) {
var staticFilePaths; sourceFiles = shortenPaths(sourceFiles, path.commonPrefix(sourceFilePaths));
var staticFileFilter; }
var staticFileScanner; data().each(function(doclet) {
if (conf['default'].staticFiles) { const url = helper.createLink(doclet);
staticFilePaths = conf['default'].staticFiles.paths || []; helper.registerLink(doclet.longname, url);
staticFileFilter = new (require('jsdoc/lib/jsdoc/src/filter')).Filter(conf['default'].staticFiles);
staticFileScanner = new (require('jsdoc/lib/jsdoc/src/scanner')).Scanner();
staticFilePaths.forEach(function(filePath) { // replace the filename with a shortened version of the full path
var extraStaticFiles = staticFileScanner.scan([filePath], 10, staticFileFilter); let docletPath;
if (doclet.meta) {
docletPath = getPathFromDoclet(doclet);
docletPath = sourceFiles[docletPath].shortened;
if (docletPath) {
doclet.meta.filename = docletPath;
}
}
});
extraStaticFiles.forEach(function(fileName) { data().each(function(doclet) {
var sourcePath = fs.statSync(filePath).isDirectory() ? filePath : const url = helper.longnameToUrl[doclet.longname];
path.dirname(filePath);
var toDir = fs.toDir( fileName.replace(sourcePath, outdir) ); if (url.indexOf('#') > -1) {
fs.mkPath(toDir); doclet.id = helper.longnameToUrl[doclet.longname].split(/#/).pop();
fs.copyFileSync(fileName, toDir); } else {
}); doclet.id = doclet.name;
});
} }
if (sourceFilePaths.length) { if (needsSignature(doclet)) {
sourceFiles = shortenPaths( sourceFiles, path.commonPrefix(sourceFilePaths) ); addSignatureParams(doclet);
addSignatureReturns(doclet);
} }
data().each(function(doclet) { });
var url = helper.createLink(doclet);
helper.registerLink(doclet.longname, url);
// replace the filename with a shortened version of the full path // do this after the urls have all been generated
var docletPath; data().each(function(doclet) {
if (doclet.meta) { doclet.ancestors = getAncestorLinks(doclet);
docletPath = getPathFromDoclet(doclet);
docletPath = sourceFiles[docletPath].shortened;
if (docletPath) {
doclet.meta.filename = docletPath;
}
}
});
data().each(function(doclet) { if (doclet.kind === 'member') {
var url = helper.longnameToUrl[doclet.longname]; addSignatureTypes(doclet);
if (url.indexOf('#') > -1) {
doclet.id = helper.longnameToUrl[doclet.longname].split(/#/).pop();
}
else {
doclet.id = doclet.name;
}
if ( needsSignature(doclet) ) {
addSignatureParams(doclet);
addSignatureReturns(doclet);
}
});
// do this after the urls have all been generated
data().each(function(doclet) {
doclet.ancestors = getAncestorLinks(doclet);
if (doclet.kind === 'member') {
addSignatureTypes(doclet);
}
if (doclet.kind === 'constant') {
addSignatureTypes(doclet);
doclet.kind = 'member';
}
});
var members = helper.getMembers(data);
members.tutorials = tutorials.children;
// add template helpers
view.find = find;
view.linkto = linkto;
view.resolveAuthorLinks = resolveAuthorLinks;
view.tutoriallink = tutoriallink;
view.htmlsafe = htmlsafe;
view.members = members; //@davidshimjs: To make navigation for customizing
// once for all
view.nav = buildNav(members);
attachModuleSymbols( find({ kind: ['class', 'function'], longname: {left: 'module:'} }),
members.modules );
// only output pretty-printed source files if requested; do this before generating any other
// pages, so the other pages can link to the source files
if (conf['default'].outputSourceFiles) {
generateSourceFiles(sourceFiles);
} }
if (members.globals.length) { generate('Global', [{kind: 'globalobj'}], globalUrl); } if (doclet.kind === 'constant') {
addSignatureTypes(doclet);
doclet.kind = 'member';
}
});
// index page displays information from package.json and lists files const members = helper.getMembers(data);
var files = find({kind: 'file'}); members.tutorials = tutorials.children;
generate('Index', // add template helpers
[{kind: 'mainpage', readme: opts.readme, longname: (opts.mainpagetitle) ? opts.mainpagetitle : 'Main Page'}].concat(files), view.find = find;
view.linkto = linkto;
view.resolveAuthorLinks = resolveAuthorLinks;
view.tutoriallink = tutoriallink;
view.htmlsafe = htmlsafe;
view.members = members; //@davidshimjs: To make navigation for customizing
// once for all
view.nav = buildNav(members);
attachModuleSymbols(find({kind: ['class', 'function'], longname: {left: 'module:'}}),
members.modules);
// only output pretty-printed source files if requested; do this before generating any other
// pages, so the other pages can link to the source files
if (conf['default'].outputSourceFiles) {
generateSourceFiles(sourceFiles);
}
if (members.globals.length) {
generate('Global', [{kind: 'globalobj'}], globalUrl);
}
// index page displays information from package.json and lists files
const files = find({kind: 'file'});
generate('Index',
[{kind: 'mainpage', readme: opts.readme, longname: (opts.mainpagetitle) ? opts.mainpagetitle : 'Main Page'}].concat(files),
indexUrl); indexUrl);
// set up the lists that we'll use to generate pages // set up the lists that we'll use to generate pages
var classes = taffy(members.classes); const classes = taffy(members.classes);
var modules = taffy(members.modules); const modules = taffy(members.modules);
var namespaces = taffy(members.namespaces); const namespaces = taffy(members.namespaces);
var mixins = taffy(members.mixins); const mixins = taffy(members.mixins);
var externals = taffy(members.externals); const externals = taffy(members.externals);
for (var longname in helper.longnameToUrl) { for (const longname in helper.longnameToUrl) {
if ( hasOwnProp.call(helper.longnameToUrl, longname) ) { if (hasOwnProp.call(helper.longnameToUrl, longname)) {
var myClasses = helper.find(classes, {longname: longname}); const myClasses = helper.find(classes, {longname: longname});
if (myClasses.length) { if (myClasses.length) {
generate('Class: ' + myClasses[0].name, myClasses, helper.longnameToUrl[longname]); generate('Class: ' + myClasses[0].name, myClasses, helper.longnameToUrl[longname]);
} }
var myModules = helper.find(modules, {longname: longname}); const myModules = helper.find(modules, {longname: longname});
if (myModules.length) { if (myModules.length) {
generate('Module: ' + myModules[0].name, myModules, helper.longnameToUrl[longname]); generate('Module: ' + myModules[0].name, myModules, helper.longnameToUrl[longname]);
} }
var myNamespaces = helper.find(namespaces, {longname: longname}); const myNamespaces = helper.find(namespaces, {longname: longname});
if (myNamespaces.length) { if (myNamespaces.length) {
generate('Namespace: ' + myNamespaces[0].name, myNamespaces, helper.longnameToUrl[longname]); generate('Namespace: ' + myNamespaces[0].name, myNamespaces, helper.longnameToUrl[longname]);
} }
var myMixins = helper.find(mixins, {longname: longname}); const myMixins = helper.find(mixins, {longname: longname});
if (myMixins.length) { if (myMixins.length) {
generate('Mixin: ' + myMixins[0].name, myMixins, helper.longnameToUrl[longname]); generate('Mixin: ' + myMixins[0].name, myMixins, helper.longnameToUrl[longname]);
} }
var myExternals = helper.find(externals, {longname: longname}); const myExternals = helper.find(externals, {longname: longname});
if (myExternals.length) { if (myExternals.length) {
generate('External: ' + myExternals[0].name, myExternals, helper.longnameToUrl[longname]); generate('External: ' + myExternals[0].name, myExternals, helper.longnameToUrl[longname]);
} }
}
} }
}
// TODO: move the tutorial functions to templateHelper.js // TODO: move the tutorial functions to templateHelper.js
function generateTutorial(title, tutorial, filename) { function generateTutorial(title, tutorial, filename) {
var tutorialData = { const tutorialData = {
title: title, title: title,
header: tutorial.title, header: tutorial.title,
content: tutorial.parse(), content: tutorial.parse(),
children: tutorial.children children: tutorial.children
}; };
var tutorialPath = path.join(outdir, filename), let html = view.render('tutorial.tmpl', tutorialData);
html = view.render('tutorial.tmpl', tutorialData); // yes, you can use {@link} in tutorials too!
html = helper.resolveLinks(html); // turn {@link foo} into <a href="foodoc.html">foo</a>
// yes, you can use {@link} in tutorials too! const tutorialPath = path.join(outdir, filename);
html = helper.resolveLinks(html); // turn {@link foo} into <a href="foodoc.html">foo</a> fs.writeFileSync(tutorialPath, html, 'utf8');
}
fs.writeFileSync(tutorialPath, html, 'utf8'); // tutorials can have only one parent so there is no risk for loops
} function saveChildren(node) {
node.children.forEach(function(child) {
// tutorials can have only one parent so there is no risk for loops generateTutorial('Tutorial: ' + child.title, child, helper.tutorialToUrl(child.name));
function saveChildren(node) { saveChildren(child);
node.children.forEach(function(child) { });
generateTutorial('Tutorial: ' + child.title, child, helper.tutorialToUrl(child.name)); }
saveChildren(child); saveChildren(tutorials);
});
}
saveChildren(tutorials);
}; };

View File

@@ -6,7 +6,7 @@
*/ */
var DEFAULT_VALUE = /default\s+is\s+`?(true|false)`?/i; const DEFAULT_VALUE = /default\s+is\s+`?(true|false)`?/i;
/** /**
@@ -19,9 +19,9 @@ exports.defineTags = function(dictionary) {
canHaveType: true, canHaveType: true,
mustHaveValue: true, mustHaveValue: true,
onTagged: function(doclet, tag) { onTagged: function(doclet, tag) {
var types = tag.value.type.names; const types = tag.value.type.names;
if (types.length === 1 && types[0] === 'boolean') { if (types.length === 1 && types[0] === 'boolean') {
var match = tag.value.description.match(DEFAULT_VALUE); const match = tag.value.description.match(DEFAULT_VALUE);
if (match) { if (match) {
doclet.define = { doclet.define = {
default: match[1] === 'true' default: match[1] === 'true'

View File

@@ -4,7 +4,7 @@
*/ */
exports.defineTags = function(dictionary) { exports.defineTags = function(dictionary) {
var classTag = dictionary.lookUp('class'); const classTag = dictionary.lookUp('class');
dictionary.defineTag('interface', { dictionary.defineTag('interface', {
mustHaveValue: false, mustHaveValue: false,
onTagged: function(doclet, tag) { onTagged: function(doclet, tag) {

View File

@@ -9,7 +9,7 @@
], ],
"homepage": "https://openlayers.org/", "homepage": "https://openlayers.org/",
"scripts": { "scripts": {
"lint": "eslint tasks test src/ol examples", "lint": "eslint tasks test src/ol examples config",
"pretest": "npm run lint", "pretest": "npm run lint",
"posttest": "npm run typecheck", "posttest": "npm run typecheck",
"test": "npm run karma -- --single-run", "test": "npm run karma -- --single-run",