mirror of
https://github.com/jsdoc/jsdoc.git
synced 2025-12-08 19:46:11 +00:00
more fixes to ensure that we always generate valid filenames (#440)
This commit is contained in:
parent
463dd0a05b
commit
77546a9d52
10
jsdoc.js
10
jsdoc.js
@ -61,6 +61,13 @@ require('lib/jsdoc/util/global').env = {
|
||||
*/
|
||||
opts: {},
|
||||
|
||||
/**
|
||||
* The source files that JSDoc will parse.
|
||||
* @type Array
|
||||
* @memberof env
|
||||
*/
|
||||
sourceFiles: [],
|
||||
|
||||
/**
|
||||
* The JSDoc version number and revision date.
|
||||
*
|
||||
@ -220,7 +227,8 @@ function main() {
|
||||
if (env.conf.source && env.opts._.length > 0) { // are there any files to scan and parse?
|
||||
filter = new jsdoc.src.filter.Filter(env.conf.source);
|
||||
|
||||
sourceFiles = app.jsdoc.scanner.scan(env.opts._, (env.opts.recurse? 10 : undefined), filter);
|
||||
env.sourceFiles = sourceFiles = app.jsdoc.scanner.scan(env.opts._,
|
||||
(env.opts.recurse? 10 : undefined), filter);
|
||||
|
||||
jsdoc.src.handlers.attachTo(app.jsdoc.parser);
|
||||
|
||||
|
||||
@ -51,7 +51,10 @@ function prefixReducer(previousPath, current) {
|
||||
* @return {string} The common prefix, or an empty string if there is no common prefix.
|
||||
*/
|
||||
exports.commonPrefix = function(paths) {
|
||||
var common = paths.reduce(prefixReducer, undefined);
|
||||
var common;
|
||||
|
||||
paths = paths || [];
|
||||
common = paths.reduce(prefixReducer, undefined) || [];
|
||||
|
||||
// if there's anything left (other than a placeholder for a leading slash), add a placeholder
|
||||
// for a trailing slash
|
||||
|
||||
@ -7,7 +7,19 @@
|
||||
@license Apache License 2.0 - See file 'LICENSE.md' in this project.
|
||||
*/
|
||||
|
||||
var path = require('path');
|
||||
var path = require('jsdoc/path');
|
||||
|
||||
function filepathMinusPrefix(filepath) {
|
||||
var sourceFiles = env.sourceFiles || [];
|
||||
var commonPrefix = path.commonPrefix( sourceFiles.concat(env.opts._ || []) );
|
||||
var result = (filepath + '/').replace(commonPrefix, '');
|
||||
|
||||
if (result.length > 0 && result[result.length - 1] !== '/') {
|
||||
result += '/';
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/** @private */
|
||||
function setDocletKindToTitle(doclet, tag) {
|
||||
@ -34,12 +46,11 @@ function setDocletDescriptionToValue(doclet, tag) {
|
||||
}
|
||||
|
||||
function setNameToFile(doclet, tag) {
|
||||
var name = '';
|
||||
var name;
|
||||
|
||||
if (doclet.meta.filename) {
|
||||
// TODO: find the shortest path shared by all input files, and remove that from
|
||||
// doclet.meta.path
|
||||
name += path.basename(doclet.meta.path) + '/';
|
||||
doclet.addTag( 'name', name + doclet.meta.filename );
|
||||
name = filepathMinusPrefix(doclet.meta.path) + doclet.meta.filename;
|
||||
doclet.addTag('name', name);
|
||||
}
|
||||
}
|
||||
|
||||
@ -64,17 +75,13 @@ function applyNamespace(docletOrNs, tag) {
|
||||
}
|
||||
|
||||
function setDocletNameToFilename(doclet, tag) {
|
||||
// TODO: find the shortest path shared by all input files, and remove that from doclet.meta.path
|
||||
var name = doclet.meta.path ? path.basename(doclet.meta.path) + '/' : '';
|
||||
name += doclet.meta.filename;
|
||||
name = name.replace(/\.js$/i, '');
|
||||
|
||||
for (var i = 0, len = env.opts._.length; i < len; i++) {
|
||||
if (name.indexOf(env.opts._[i]) === 0) {
|
||||
name = name.replace(env.opts._[0], '');
|
||||
break;
|
||||
}
|
||||
var name = '';
|
||||
|
||||
if (doclet.meta.path) {
|
||||
name = filepathMinusPrefix(doclet.meta.path);
|
||||
}
|
||||
name += doclet.meta.filename.replace(/\.js$/i, '');
|
||||
|
||||
doclet.name = name;
|
||||
}
|
||||
|
||||
|
||||
@ -52,6 +52,8 @@ function makeFilenameUnique(filename, str) {
|
||||
}
|
||||
|
||||
function cleanseFilename(str) {
|
||||
str = str || '';
|
||||
|
||||
// allow for namespace prefix
|
||||
return str.replace(/^(event|module|external|package):/, '$1-')
|
||||
// use - instead of ~ to denote 'inner'
|
||||
@ -702,28 +704,46 @@ function getFilename(longname) {
|
||||
|
||||
/** Turn a doclet into a URL. */
|
||||
exports.createLink = function(doclet) {
|
||||
var filename;
|
||||
var fragment;
|
||||
var match;
|
||||
var fakeContainer;
|
||||
|
||||
var url = '';
|
||||
var longname = doclet.longname;
|
||||
var filename;
|
||||
|
||||
var fakeContainerMatch = /(\S+):/.exec(longname);
|
||||
|
||||
// handle doclets in which doclet.longname implies that the doclet gets its own HTML file, but
|
||||
// doclet.kind says otherwise. this happens due to mistagged JSDoc (for example, a module that
|
||||
// somehow has doclet.kind set to `member`).
|
||||
// TODO: generate a warning (ideally during parsing!)
|
||||
if (containers.indexOf(doclet.kind) === -1) {
|
||||
match = /(\S+):/.exec(longname);
|
||||
if (match && containers.indexOf(match[1]) !== -1) {
|
||||
fakeContainer = match[1];
|
||||
}
|
||||
}
|
||||
|
||||
// the doclet gets its own HTML file
|
||||
if ( containers.indexOf(doclet.kind) !== -1 || isModuleFunction(doclet) ) {
|
||||
url = getFilename(longname);
|
||||
filename = getFilename(longname);
|
||||
}
|
||||
// the doclet's longname suggests that it should get its own HTML file, but doclet.kind says
|
||||
// otherwise. this happens due to mistagged JSDoc (for example, a module that somehow has
|
||||
// doclet.kind set to `member`). use the container's filename plus a fragment.
|
||||
else if ( containers.indexOf(doclet.kind) === -1 && fakeContainerMatch &&
|
||||
containers.indexOf(fakeContainerMatch[1]) !== -1 ) {
|
||||
url = getFilename(longname) + '#' + doclet.name;
|
||||
// mistagged version of a doclet that gets its own HTML file
|
||||
else if ( containers.indexOf(doclet.kind) === -1 && fakeContainer ) {
|
||||
filename = getFilename(doclet.memberof || longname);
|
||||
if (doclet.name === doclet.longname) {
|
||||
fragment = '';
|
||||
}
|
||||
else {
|
||||
fragment = doclet.name || '';
|
||||
}
|
||||
}
|
||||
// the doclet is within another HTML file
|
||||
else {
|
||||
filename = getFilename(doclet.memberof || exports.globalName);
|
||||
url = filename + '#' + getNamespace(doclet.kind) + doclet.name;
|
||||
fragment = getNamespace(doclet.kind) + (doclet.name || '');
|
||||
}
|
||||
|
||||
url = fragment ? (filename + '#' + fragment) : filename;
|
||||
|
||||
return url;
|
||||
};
|
||||
|
||||
@ -1,14 +1,20 @@
|
||||
/*global beforeEach: true, describe: true, env: true, expect: true, it: true */
|
||||
/*global afterEach: true, beforeEach: true, describe: true, env: true, expect: true, it: true */
|
||||
describe("module names", function() {
|
||||
var parser = require('jsdoc/src/parser'),
|
||||
srcParser = null, doclets;
|
||||
var parser = require('jsdoc/src/parser');
|
||||
var srcParser = null;
|
||||
var doclets;
|
||||
var sourcePaths = env.opts._.slice(0);
|
||||
|
||||
beforeEach(function() {
|
||||
env.opts._ = [__dirname + '/test/fixtures/modules/'];
|
||||
env.opts._ = [__dirname + '/test/fixtures/modules/data/'];
|
||||
srcParser = new parser.Parser();
|
||||
require('jsdoc/src/handlers').attachTo(srcParser);
|
||||
});
|
||||
|
||||
afterEach(function() {
|
||||
env.opts._ = sourcePaths;
|
||||
});
|
||||
|
||||
it("should create a name from the file path when no documented module name exists", function() {
|
||||
doclets = srcParser.parse(__dirname + '/test/fixtures/modules/data/mod-1.js');
|
||||
expect(doclets.length).toBeGreaterThan(1);
|
||||
|
||||
@ -1379,20 +1379,53 @@ describe("jsdoc/util/templateHelper", function() {
|
||||
it('should create a url for a doclet with the wrong kind (caused by incorrect JSDoc tags', function() {
|
||||
var moduleDoclet = {
|
||||
kind: 'module',
|
||||
longname: 'module:bar',
|
||||
name: 'module:bar'
|
||||
longname: 'module:baz',
|
||||
name: 'module:baz'
|
||||
};
|
||||
var badDoclet = {
|
||||
kind: 'member',
|
||||
longname: 'module:bar',
|
||||
name: 'module:bar'
|
||||
longname: 'module:baz',
|
||||
name: 'module:baz'
|
||||
};
|
||||
|
||||
var moduleDocletUrl = helper.createLink(moduleDoclet);
|
||||
var badDocletUrl = helper.createLink(badDoclet);
|
||||
|
||||
expect(moduleDocletUrl).toBe('module-bar.html');
|
||||
expect(badDocletUrl).toBe('module-bar.html#module:bar');
|
||||
expect(moduleDocletUrl).toBe('module-baz.html');
|
||||
expect(badDocletUrl).toBe('module-baz.html');
|
||||
});
|
||||
|
||||
it('should create a url for a function that is a member of a doclet with the wrong kind', function() {
|
||||
var badModuleDoclet = {
|
||||
kind: 'member',
|
||||
longname: 'module:qux',
|
||||
name: 'module:qux'
|
||||
};
|
||||
var memberDoclet = {
|
||||
kind: 'function',
|
||||
name: 'frozzle',
|
||||
memberof: 'module:qux',
|
||||
scope: 'instance',
|
||||
longname: 'module:qux#frozzle'
|
||||
};
|
||||
|
||||
var badModuleDocletUrl = helper.createLink(badModuleDoclet);
|
||||
var memberDocletUrl = helper.createLink(memberDoclet);
|
||||
|
||||
expect(badModuleDocletUrl).toBe('module-qux.html');
|
||||
expect(memberDocletUrl).toBe('module-qux.html#frozzle');
|
||||
});
|
||||
|
||||
it('should create a url for an empty package definition', function() {
|
||||
var packageDoclet = {
|
||||
kind: 'package',
|
||||
name: undefined,
|
||||
longname: 'package:undefined'
|
||||
};
|
||||
|
||||
var packageDocletUrl = helper.createLink(packageDoclet);
|
||||
|
||||
expect(packageDocletUrl).toBe('global.html');
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
@ -1,18 +1,28 @@
|
||||
/*global describe: true, env: true, expect: true, it: true */
|
||||
/*global beforeEach: true, afterEach: true, describe: true, env: true, expect: true, it: true */
|
||||
|
||||
describe("@overview tag", function() {
|
||||
var parser = require('jsdoc/src/parser'),
|
||||
srcParser = new parser.Parser(),
|
||||
doclets;
|
||||
var parser = require('jsdoc/src/parser');
|
||||
var srcParser = null;
|
||||
var doclets;
|
||||
var sourcePaths = env.opts._.slice(0);
|
||||
|
||||
require('jsdoc/src/handlers').attachTo(srcParser);
|
||||
doclets = srcParser.parse(__dirname + '/test/fixtures/file.js');
|
||||
beforeEach(function() {
|
||||
env.opts._ = [__dirname + '/test/fixtures/'];
|
||||
srcParser = new parser.Parser();
|
||||
require('jsdoc/src/handlers').attachTo(srcParser);
|
||||
});
|
||||
|
||||
afterEach(function() {
|
||||
env.opts._ = sourcePaths;
|
||||
});
|
||||
|
||||
it('When a file overview tag appears in a doclet, the name of the doclet should contain the path to the file.', function() {
|
||||
doclets = srcParser.parse(__dirname + '/test/fixtures/file.js');
|
||||
expect(doclets[0].name).toMatch(/^(fixtures[\/\\]file\.js)$/);
|
||||
});
|
||||
|
||||
it("The name and longname should be equal", function() {
|
||||
doclets = srcParser.parse(__dirname + '/test/fixtures/file.js');
|
||||
expect(doclets[0].name).toBe(doclets[0].longname);
|
||||
});
|
||||
});
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user