mirror of
https://github.com/jsdoc/jsdoc.git
synced 2025-12-08 19:46:11 +00:00
Merge branch 'master' into parsimony
Conflicts: lib/jsdoc/src/parser.js test/specs/tags/defaulttag.js
This commit is contained in:
commit
da22d723b7
@ -11,7 +11,7 @@ This file describes notable changes in each version of JSDoc 3. To download a sp
|
||||
|
||||
### Enhancements
|
||||
+ The parser now fires a `parseBegin` event before it starts parsing files, as well as a `parseComplete` event after all files have been parsed. Plugins can define event handlers for these events, and `parseBegin` handlers can modify the list of files to parse. (#299)
|
||||
+ Event handlers for `jsdocCommentFount` events can now modify the JSDoc comment. (#228)
|
||||
+ Event handlers for `jsdocCommentFound` events can now modify the JSDoc comment. (#228)
|
||||
+ You can now exclude tags from Markdown processing using the new option `markdown.excludeTags` in the configuration file. (#337)
|
||||
+ You can now use the [marked](https://github.com/chjj/marked) Markdown parser by setting the configuration property `markdown.parser` to `marked`. In addition, if `markdown.parser` is set to `gfm`, JSDoc will now use the "marked" parser instead. (#385)
|
||||
+ The `@typedef` tag no longer requires a name when used with a Closure Compiler-style type definition. For example, the following type definition will automatically get the name `Foo.Bar`:
|
||||
|
||||
4
jsdoc.js
4
jsdoc.js
@ -170,7 +170,7 @@ function main() {
|
||||
env.opts = jsdoc.opts.args.parse(env.args);
|
||||
|
||||
confPath = env.opts.configure || path.join(__dirname, 'conf.json');
|
||||
if ( !fs.statSync(confPath).isFile() ) {
|
||||
if ( !fs.statSync(confPath).isFile() && !env.opts.configure ) {
|
||||
confPath = path.join(__dirname, 'conf.json.EXAMPLE');
|
||||
}
|
||||
|
||||
@ -237,6 +237,8 @@ function main() {
|
||||
jsdoc.augment.addInherited(docs);
|
||||
jsdoc.borrow.resolveBorrows(docs);
|
||||
|
||||
app.jsdoc.parser.fireProcessingComplete(docs);
|
||||
|
||||
if (env.opts.explain) {
|
||||
dump(docs);
|
||||
process.exit(0);
|
||||
|
||||
@ -90,7 +90,10 @@ function getAdditions(doclets, docs, longnames) {
|
||||
for (var k = 0, kk = members.length; k < kk; k++) {
|
||||
member = doop(members[k]);
|
||||
|
||||
member.inherits = member.longname;
|
||||
if(!member.inherited)
|
||||
{
|
||||
member.inherits = member.longname;
|
||||
}
|
||||
member.inherited = true;
|
||||
|
||||
member.memberof = doc.longname;
|
||||
|
||||
@ -128,7 +128,12 @@ Parser.prototype.parse = function(sourceFiles, encoding) {
|
||||
return this._resultBuffer;
|
||||
};
|
||||
|
||||
// TODO: update docs
|
||||
// TODO: docs
|
||||
Parser.prototype.fireProcessingComplete = function(doclets) {
|
||||
this.emit('processingComplete', { doclets: doclets });
|
||||
};
|
||||
|
||||
// TODO: docs
|
||||
/**
|
||||
* @returns {Array<Doclet>} The accumulated results of any calls to parse.
|
||||
*/
|
||||
|
||||
@ -246,6 +246,10 @@ exports.defineTags = function(dictionary) {
|
||||
if (type === Syntax.Literal) {
|
||||
doclet.defaultvalue = String(value);
|
||||
}
|
||||
else if (doclet.meta.code.type === 'OBJECTLIT') {
|
||||
doclet.defaultvalue = String(doclet.meta.code.node.toSource());
|
||||
doclet.defaultvaluetype = 'object';
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
@ -61,7 +61,7 @@ exports.replaceInlineTags = function(string, replacers) {
|
||||
|
||||
string = string || '';
|
||||
Object.keys(replacers).forEach(function(replacer) {
|
||||
var tagRegExp = new RegExp('\\{@' + replacer + '\\s+(.+?)\\}', 'gi');
|
||||
var tagRegExp = new RegExp('\\{@' + replacer + '\\s+((?:.|\n)+?)\\}', 'gi');
|
||||
var matches;
|
||||
// call the replacer once for each match
|
||||
while ( (matches = tagRegExp.exec(string)) !== null ) {
|
||||
|
||||
@ -256,11 +256,13 @@ function splitLinkText(text) {
|
||||
// if a pipe is not present, we split on the first space
|
||||
splitIndex = text.indexOf('|');
|
||||
if (splitIndex === -1) {
|
||||
splitIndex = text.indexOf(' ');
|
||||
splitIndex = text.search(/\s/);
|
||||
}
|
||||
|
||||
if (splitIndex !== -1) {
|
||||
linkText = text.substr(splitIndex + 1);
|
||||
// Normalize subsequent newlines to a single space.
|
||||
linkText = linkText.replace(/\n+/, ' ');
|
||||
target = text.substr(0, splitIndex);
|
||||
}
|
||||
|
||||
|
||||
@ -19,7 +19,8 @@ var events = conf.include || [
|
||||
'symbolFound',
|
||||
'newDoclet',
|
||||
'fileComplete',
|
||||
'parseComplete'
|
||||
'parseComplete',
|
||||
'processingComplete'
|
||||
];
|
||||
// Don't dump the excluded parser events
|
||||
if (conf.exclude) {
|
||||
|
||||
@ -195,12 +195,14 @@ h6
|
||||
font-family: Consolas, "Lucida Console", Monaco, monospace;
|
||||
}
|
||||
|
||||
.details { margin-top: 14px; }
|
||||
.details dt { width:100px; float:left; border-left: 2px solid #DDD; padding-left: 10px; padding-top: 6px; }
|
||||
.details { margin-top: 14px; border-left: 2px solid #DDD; }
|
||||
.details dt { width:100px; float:left; padding-left: 10px; padding-top: 6px; }
|
||||
.details dd { margin-left: 50px; }
|
||||
.details ul { margin: 0; }
|
||||
.details ul { list-style-type: none; }
|
||||
.details li { margin-left: 30px; padding-top: 6px; }
|
||||
.details pre.prettyprint { margin: 0 }
|
||||
.details .object-value { padding-top: 0; }
|
||||
|
||||
.description {
|
||||
margin-bottom: 1em;
|
||||
|
||||
@ -1,6 +1,13 @@
|
||||
<?js
|
||||
var data = obj;
|
||||
var self = this;
|
||||
var defaultObjectClass = '';
|
||||
|
||||
// Check if the default value is an object, if so, apply code highlighting
|
||||
if (data.defaultvalue && data.defaultvaluetype === 'object') {
|
||||
data.defaultvalue = "<pre class=\"prettyprint\"><code>" + data.defaultvalue + "</code></pre>";
|
||||
defaultObjectClass = ' class="object-value"';
|
||||
}
|
||||
?>
|
||||
<dl class="details">
|
||||
<?js
|
||||
@ -59,7 +66,9 @@ var self = this;
|
||||
|
||||
<?js if (data.defaultvalue) {?>
|
||||
<dt class="tag-default">Default Value:</dt>
|
||||
<dd class="tag-default"><ul class="dummy"><li><?js= data.defaultvalue ?></li></ul></dd>
|
||||
<dd class="tag-default"><ul class="dummy">
|
||||
<li<?js= defaultObjectClass ?>><?js= data.defaultvalue ?></li>
|
||||
</ul></dd>
|
||||
<?js } ?>
|
||||
|
||||
<?js if (data.meta) {?>
|
||||
|
||||
15
test/fixtures/defaulttag.js
vendored
15
test/fixtures/defaulttag.js
vendored
@ -31,4 +31,17 @@ var win = getParentWindow();
|
||||
/**
|
||||
@default
|
||||
*/
|
||||
var header = getHeaders(request);
|
||||
var header = getHeaders(request);
|
||||
|
||||
/**
|
||||
@default
|
||||
*/
|
||||
var obj = { value_a : 'a', value_b : 'b' };
|
||||
|
||||
/**
|
||||
* @default
|
||||
*/
|
||||
var multilineObject = {
|
||||
value_a : 'a',
|
||||
value_b : 'b'
|
||||
};
|
||||
|
||||
@ -2,7 +2,7 @@
|
||||
describe("jsdoc/src/filter", function() {
|
||||
var filter = new (require('jsdoc/src/filter').Filter)({
|
||||
includePattern: new RegExp(".+\\.js(doc)?$"),
|
||||
excludePattern: new RegExp("(^|\\/)_"),
|
||||
excludePattern: new RegExp("(^|\\/|\\\\)_"),
|
||||
exclude: ['.ignore', 'scratch/conf.js']
|
||||
});
|
||||
|
||||
|
||||
@ -77,6 +77,16 @@ describe("jsdoc/src/parser", function() {
|
||||
expect(spy).toHaveBeenCalled();
|
||||
expect(spy.mostRecentCall.args[0].sourcefiles).toEqual(["[[string0]]"]);
|
||||
});
|
||||
|
||||
it("should fire processingComplete when fireProcessingComplete is called", function() {
|
||||
var spy = jasmine.createSpy(),
|
||||
doclets = ['a','b'];
|
||||
parser.on('processingComplete', spy).fireProcessingComplete(doclets);
|
||||
expect(spy).toHaveBeenCalled();
|
||||
expect(typeof spy.mostRecentCall.args[0]).toBe('object');
|
||||
expect(spy.mostRecentCall.args[0].doclets).toBeDefined();
|
||||
expect(spy.mostRecentCall.args[0].doclets).toBe(doclets);
|
||||
});
|
||||
|
||||
it("should be able to parse its own source file", function() {
|
||||
var fs = require('jsdoc/fs'),
|
||||
|
||||
@ -1168,6 +1168,22 @@ describe("jsdoc/util/templateHelper", function() {
|
||||
expect(output).toBe('This is a <a href="path/to/test.html">test</a>.');
|
||||
});
|
||||
|
||||
it('should allow linebreaks to separate url from link text', function() {
|
||||
var input = 'This is a {@link\ntest\ntest}.',
|
||||
output = helper.resolveLinks(input);
|
||||
|
||||
expect(output).toBe('This is a <a href="path/to/test.html">test</a>.');
|
||||
});
|
||||
|
||||
|
||||
it('should normalize additional newlines to spaces', function() {
|
||||
var input = 'This is a {@link\ntest\ntest\n\ntest}.',
|
||||
output = helper.resolveLinks(input);
|
||||
|
||||
expect(output).toBe('This is a <a href="path/to/test.html">test test</a>.');
|
||||
});
|
||||
|
||||
|
||||
it('should allow tabs between link tag and content', function() {
|
||||
var input = 'This is a {@link\ttest}.',
|
||||
output = helper.resolveLinks(input);
|
||||
|
||||
@ -80,6 +80,15 @@
|
||||
expect(bazMethod3.memberof).toBe("Baz");
|
||||
});
|
||||
|
||||
it('(Grand)children correctly identify the original source of inherited members', function(){
|
||||
expect(fooProp1.inherits).not.toBeDefined();
|
||||
expect(barProp3.inherits).not.toBeDefined();
|
||||
expect(barProp1.inherits).toBe("Foo#prop1");
|
||||
expect(bazProp2.inherits).toBe("Foo#prop2");
|
||||
expect(bazProp3.inherits).toBe("Bar#prop3");
|
||||
expect(bazMethod1.inherits).toBe("Foo#method1");
|
||||
});
|
||||
|
||||
it('When an object is extended, and it overrides an ancestor property, the child does not include docs for the ancestor property.', function() {
|
||||
expect(bazProp1All.length).toBe(1);
|
||||
});
|
||||
|
||||
@ -8,6 +8,8 @@ describe("@default tag", function() {
|
||||
var rerrored = (docSet.getByLongname('rerrored') || [])[0];
|
||||
var win = (docSet.getByLongname('win') || [])[0];
|
||||
var header = (docSet.getByLongname('header') || [])[0];
|
||||
var obj = docSet.getByLongname('obj')[0];
|
||||
var multilineObject = docSet.getByLongname('multilineObject')[0];
|
||||
|
||||
it('When symbol set to null has a @default tag with no text, the doclet\'s defaultValue property should be: null', function() {
|
||||
expect(request.defaultvalue).toBe('null');
|
||||
@ -37,4 +39,14 @@ describe("@default tag", function() {
|
||||
expect(header.defaultvalue).toBeUndefined();
|
||||
});
|
||||
|
||||
it('When symbol has a @default tag with an object, the doclet\'s defaultValue property should contain the stringified object', function() {
|
||||
var expected_value = "{value_a: 'a', value_b: 'b'}";
|
||||
expect(obj.defaultvalue).toEqual(expected_value);
|
||||
});
|
||||
|
||||
it('When symbol has a @default tag with a multiline object, the doclet\'s defaultValue property should contain the properly stringified object', function() {
|
||||
var expected_value = "{value_a: 'a', value_b: 'b'}";
|
||||
expect(obj.defaultvalue).toEqual(expected_value);
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
@ -2,21 +2,21 @@ describe("@example tag", function() {
|
||||
var docSet = jasmine.getDocSetFromFile('test/fixtures/exampletag.js'),
|
||||
doc = docSet.getByLongname('x')[0],
|
||||
doc2 = docSet.getByLongname('y')[0],
|
||||
txt = 'console.log("foo");\nconsole.log("bar");',
|
||||
txt2 = '<caption>Example 2</caption>\n1 + 2;';
|
||||
txtRegExp = new RegExp('console\\.log\\("foo"\\);[\\r\\n]{1,2}console\\.log\\("bar"\\);'),
|
||||
txt2RegExp = new RegExp('<caption>Example 2</caption>[\\r\\n]{1,2}1 \\+ 2;');
|
||||
|
||||
it("creates an 'examples' property on the doclet with the example", function() {
|
||||
expect(doc.examples).toBeDefined();
|
||||
expect(Array.isArray(doc.examples)).toBe(true);
|
||||
expect(doc.examples.length).toBe(1);
|
||||
expect(doc.examples).toContain(txt);
|
||||
expect(doc.examples).toMatch(txtRegExp);
|
||||
});
|
||||
|
||||
it("can be specified multiple times on one doclet", function() {
|
||||
expect(doc2.examples).toBeDefined();
|
||||
expect(Array.isArray(doc2.examples)).toBe(true);
|
||||
expect(doc2.examples.length).toBe(2);
|
||||
expect(doc2.examples).toContain(txt);
|
||||
expect(doc2.examples).toContain(txt2);
|
||||
expect(doc2.examples).toMatch(txtRegExp);
|
||||
expect(doc2.examples).toMatch(txt2RegExp);
|
||||
});
|
||||
});
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user