From 6917abcc4ff7d6db8e221ad312a35aaad75a43b8 Mon Sep 17 00:00:00 2001 From: Michael Mathews Date: Sat, 5 Feb 2011 23:35:56 +0000 Subject: [PATCH 1/9] Updated package.json to include new svn repo. --- README.md | 1 + build.xml | 61 +++++++++++++++++++----------------- build/templates/package.json | 19 ++++++----- 3 files changed, 45 insertions(+), 36 deletions(-) diff --git a/README.md b/README.md index 445470ab..54c7df3a 100644 --- a/README.md +++ b/README.md @@ -36,6 +36,7 @@ See --- Project Documentation: +Subversion Mirror: License ------- diff --git a/build.xml b/build.xml index 35ec0685..191991dc 100644 --- a/build.xml +++ b/build.xml @@ -1,34 +1,38 @@ - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + - - + + - - + + + @@ -59,8 +63,9 @@ + - - + + \ No newline at end of file diff --git a/build/templates/package.json b/build/templates/package.json index 746ac786..3a39d8d9 100644 --- a/build/templates/package.json +++ b/build/templates/package.json @@ -7,27 +7,30 @@ "licenses": [ { "type": "Apache 2.0", - "url": "http://www.apache.org/licenses/LICENSE-2.0" + "url": "http://www.apache.org/licenses/LICENSE-2.0" } ], "repositories": [ { "type": "git", - "url": "http://github.com/micmath/JSDoc" + "url": "git://github.com/micmath/jsdoc.git" + }, + { + "type": "svn", + "url": "https://jsdoc.googlecode.com/svn/trunk" } ], + "bugs": "http://code.google.com/p/jsdoc/issues/list", "contributors" : [ { - "name": "Michael Mathews", - "email": "micmath@gmail.com", - "web": "http://micmath.ws" + "name": "Michael Mathews", + "email": "micmath@gmail.com" } ], "maintainers": [ { - "name": "Michael Mathews", - "email": "micmath@gmail.com", - "web": "http://micmath.ws" + "name": "Michael Mathews", + "email": "micmath@gmail.com" } ] } From 602c41680de14863e774ab643273fce37e56c3fd Mon Sep 17 00:00:00 2001 From: Michael Mathews Date: Sun, 6 Feb 2011 00:41:40 +0000 Subject: [PATCH 2/9] Added support for the @also pragma, to allow multiple doclets to be associated with the same line of source code. Tweaks to the default template. --- modules/jsdoc/package.js | 8 ++++-- modules/jsdoc/src/handlers.js | 12 ++++++-- package.json | 21 ++++++++------ templates/default/tmpl/container.mustache | 24 ++++++++++------ templates/default/tmpl/properties.mustache | 33 ++++++++++++++++++++-- 5 files changed, 74 insertions(+), 24 deletions(-) diff --git a/modules/jsdoc/package.js b/modules/jsdoc/package.js index 84a41932..e4fcbf25 100644 --- a/modules/jsdoc/package.js +++ b/modules/jsdoc/package.js @@ -23,12 +23,14 @@ /** The kind of this package. @readonly @default + @type {string} */ this.kind = 'package'; json = JSON.parse(json); /** The name of this package. + This value is found in the package.json file passed in as a command line option. @type {string} */ this.name = json.name; @@ -43,8 +45,10 @@ */ this.description = json.description; - /** The version of this package. + /** + The hash summary of the source file. @type {string} + @since 3.2.0 */ this.version = json.version; @@ -55,7 +59,7 @@ * "licenses": [ * { * "type": "GPLv2", - * "url": "http://www.example.com/licenses/gpl.html", + * "url": "http://www.example.com/licenses/gpl.html" * } * ] */ diff --git a/modules/jsdoc/src/handlers.js b/modules/jsdoc/src/handlers.js index 368cb5e0..20cc02de 100644 --- a/modules/jsdoc/src/handlers.js +++ b/modules/jsdoc/src/handlers.js @@ -27,7 +27,15 @@ // handles named symbols in the code, may or may not have a JSDoc comment attached parser.on('symbolFound', function(e) { - var newDoclet = new jsdoc.doclet.Doclet(e.comment, e); + var subDoclets = e.comment.split(/@also\b/g); + + for (var i = 0, l = subDoclets.length; i < l; i++) { + newSymbolDoclet.call(this, subDoclets[i], e); + } + }); + + function newSymbolDoclet(docletSrc, e) { + var newDoclet = new jsdoc.doclet.Doclet(docletSrc, e); // an undocumented symbol right after a virtual comment? rhino mistakenly connected the two if (newDoclet.name) { // there was a @name in comment @@ -92,7 +100,7 @@ addDoclet.call(this, newDoclet); e.doclet = newDoclet; - }); + } //parser.on('fileBegin', function(e) { }); diff --git a/package.json b/package.json index cd417eeb..463fe830 100644 --- a/package.json +++ b/package.json @@ -1,33 +1,36 @@ { "name": "jsdoc", "version": "3.0.0beta1", - "revision": "2011-02-05-2259", + "revision": "2011-02-06-0040", "description": "An automatic documentation generator for javascript.", "keywords": [ "documentation", "javascript" ], "licenses": [ { "type": "Apache 2.0", - "url": "http://www.apache.org/licenses/LICENSE-2.0" + "url": "http://www.apache.org/licenses/LICENSE-2.0" } ], "repositories": [ { "type": "git", - "url": "http://github.com/micmath/JSDoc" + "url": "git://github.com/micmath/jsdoc.git" + }, + { + "type": "svn", + "url": "https://jsdoc.googlecode.com/svn/trunk" } ], + "bugs": "http://code.google.com/p/jsdoc/issues/list", "contributors" : [ { - "name": "Michael Mathews", - "email": "micmath@gmail.com", - "web": "http://micmath.ws" + "name": "Michael Mathews", + "email": "micmath@gmail.com" } ], "maintainers": [ { - "name": "Michael Mathews", - "email": "micmath@gmail.com", - "web": "http://micmath.ws" + "name": "Michael Mathews", + "email": "micmath@gmail.com" } ] } diff --git a/templates/default/tmpl/container.mustache b/templates/default/tmpl/container.mustache index 670e77e2..b1b7218d 100644 --- a/templates/default/tmpl/container.mustache +++ b/templates/default/tmpl/container.mustache @@ -194,19 +194,19 @@ margin-left: 30px; } .property-head { - margin-left: -30px; + margin-left: -20px; display: block; line-height: 1.2em; } - .property-head h4 { - color: #4782B5; - } - .property-title { + .property-name { float: left; margin: 0; - padding: 0 20px 0 0; - font-style: italic; + padding: 0 10px 0 0; + + font-style: italic; + font-weight: bold; font-size: 1.2em; + color: #4782B5; } .property-summary { color: #999; @@ -219,8 +219,16 @@ .property-details dt { font-weight: bold; margin-bottom: 4px; + padding-left: 10px; + clear: left; + float: left; + } + .property-details dd { + padding-left: 60px; + } + .property-deprecated { + text-decoration: line-through; } - .example-code { border: 1px solid #999; diff --git a/templates/default/tmpl/properties.mustache b/templates/default/tmpl/properties.mustache index 01dd6f2e..e3763428 100644 --- a/templates/default/tmpl/properties.mustache +++ b/templates/default/tmpl/properties.mustache @@ -1,8 +1,8 @@
-
+
-

{{name}}

+ {{name}}
{{{summary}}} @@ -15,9 +15,30 @@
{{{description}}} +
{{/description}} + {{#deprecated}} +
+ Deprecated +
+
+ {{{deprecated}}} +
+
+ {{/deprecated}} + + {{#since}} +
+ Since +
+
+ {{{since}}} +
+
+ {{/since}} + {{#type}}
Type @@ -26,6 +47,7 @@ {{#names}} {{#linkTo}}{{.}}{{/linkTo}}{{^last?}} | {{/last?}}{{#last?}} {{/last?}} {{/names}} +
{{/type}} @@ -35,6 +57,7 @@
Yes +
{{/readonly}} @@ -44,15 +67,17 @@
Yes +
{{/nullable}} {{#defaultvalue}}
- Default Value + Default
{{defaultvalue}} +
{{/defaultvalue}} @@ -61,9 +86,11 @@ Example
+
{{.}}
+
{{/examples}}
From 51243ece55d10020c1f516bb732a5b2627121727 Mon Sep 17 00:00:00 2001 From: Michael Mathews Date: Sun, 6 Feb 2011 10:35:14 +0000 Subject: [PATCH 3/9] Doclets that are immediately adjacent to each other are now considered @also docs. --- modules/jsdoc/src/parser.js | 3 +++ test/cases/also.js | 20 ++++++++++++++++++++ test/runner.js | 2 ++ test/t/cases/also.js | 13 +++++++++++++ 4 files changed, 38 insertions(+) create mode 100644 test/cases/also.js create mode 100644 test/t/cases/also.js diff --git a/modules/jsdoc/src/parser.js b/modules/jsdoc/src/parser.js index 69d07535..a4722b37 100644 --- a/modules/jsdoc/src/parser.js +++ b/modules/jsdoc/src/parser.js @@ -93,6 +93,9 @@ Parser.prototype._parseSourceCode = function(sourceCode, sourceName) { currentSourceName = sourceName; + // merge adjacent doclets + sourceCode = sourceCode.replace(/\*\/\/\*\*+/g, '@also'); + var ast = parserFactory().parse(sourceCode, sourceName, 1); var e = {filename: currentSourceName}; diff --git a/test/cases/also.js b/test/cases/also.js new file mode 100644 index 00000000..602bc041 --- /dev/null +++ b/test/cases/also.js @@ -0,0 +1,20 @@ +/** @class */ +function Asset() { + this._name = ''; +} + +/** + * + * Set the value of the name property. + * @param {string} newName + * + *//** + * + * Get the value of the name property. + * @returns {string} + * + */ +Asset.prototype.name = function(newName) { + if (newName) { this._name = newName; } + else { return this._name; } +} \ No newline at end of file diff --git a/test/runner.js b/test/runner.js index af8bafd0..9e0d657e 100644 --- a/test/runner.js +++ b/test/runner.js @@ -86,10 +86,12 @@ testFile('test/t/cases/inner.js'); testFile('test/t/cases/modules/data/mod-1.js'); testFile('test/t/cases/modules/data/mod-2.js'); + testFile('test/t/cases/accesstag.js'); testFile('test/t/cases/alias.js'); testFile('test/t/cases/alias2.js'); testFile('test/t/cases/alias3.js'); +testFile('test/t/cases/also.js'); testFile('test/t/cases/augmentstag.js'); testFile('test/t/cases/authortag.js'); testFile('test/t/cases/borrowstag.js'); diff --git a/test/t/cases/also.js b/test/t/cases/also.js new file mode 100644 index 00000000..a48b2381 --- /dev/null +++ b/test/t/cases/also.js @@ -0,0 +1,13 @@ +(function() { + var docSet = testhelpers.getDocSetFromFile('test/cases/also.js'), + name = docSet.getByLongname('Asset#name').filter(function($) { + return ! $.undocumented; + }); + + //dump(name); + + test('When a symbol has two doclets adjacent to each other both doclets apply to the symbol.', function() { + assert.equal(name.length, 2, 'myObject'); + }); + +})(); \ No newline at end of file From 228835ec1f6cb02f49924d6ea4c62f4808a295a3 Mon Sep 17 00:00:00 2001 From: Michael Mathews Date: Tue, 8 Feb 2011 20:04:49 +0000 Subject: [PATCH 4/9] Added support for @typedef tag. --- modules/jsdoc/src/parser.js | 2 +- modules/jsdoc/tag/dictionary/definitions.js | 19 +++++++++++++++- package.json | 2 +- test/cases/typedeftag.js | 5 +++++ test/runner.js | 1 + test/t/cases/typedeftag.js | 24 +++++++++++++++++++++ 6 files changed, 50 insertions(+), 3 deletions(-) create mode 100644 test/cases/typedeftag.js create mode 100644 test/t/cases/typedeftag.js diff --git a/modules/jsdoc/src/parser.js b/modules/jsdoc/src/parser.js index a4722b37..246b94dc 100644 --- a/modules/jsdoc/src/parser.js +++ b/modules/jsdoc/src/parser.js @@ -195,7 +195,7 @@ function visitNode(node) { var e, commentSrc; - + // look for stand-alone doc comments if (node.type === Token.SCRIPT && node.comments) { // note: ALL comments are seen in this block... diff --git a/modules/jsdoc/tag/dictionary/definitions.js b/modules/jsdoc/tag/dictionary/definitions.js index 5bab8c11..f5e0557d 100644 --- a/modules/jsdoc/tag/dictionary/definitions.js +++ b/modules/jsdoc/tag/dictionary/definitions.js @@ -399,7 +399,24 @@ onTagged: function(doclet, tag) { if (tag.value.type) { doclet.type = tag.value.type; } } - }) + }); + + dictionary.defineTag('typedef', { + canHaveType: true, + canHaveName: true, + onTagged: function(doclet, tag) { + setDocletKindToTitle(doclet, tag); + + if (tag.value) { + if (tag.value.name) { + doclet.addTag('name', tag.value.name); + } + if (tag.value.type) { + doclet.type = tag.value.type; + } + } + } + }); dictionary.defineTag('undocumented', { mustNotHaveValue: true, diff --git a/package.json b/package.json index 463fe830..9547be1e 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "jsdoc", "version": "3.0.0beta1", - "revision": "2011-02-06-0040", + "revision": "2011-02-08-2004", "description": "An automatic documentation generator for javascript.", "keywords": [ "documentation", "javascript" ], "licenses": [ diff --git a/test/cases/typedeftag.js b/test/cases/typedeftag.js new file mode 100644 index 00000000..9d82cfdc --- /dev/null +++ b/test/cases/typedeftag.js @@ -0,0 +1,5 @@ +/** @typedef {(string|number)} calc.NumberLike */ + +/** @param {calc.NumberLike} x A number or a string. */ +calc.readNumber = function(x) { +} \ No newline at end of file diff --git a/test/runner.js b/test/runner.js index 9e0d657e..4a36488f 100644 --- a/test/runner.js +++ b/test/runner.js @@ -122,6 +122,7 @@ testFile('test/t/cases/seetag.js'); testFile('test/t/cases/sincetag.js'); testFile('test/t/cases/thistag.js'); testFile('test/t/cases/typetag.js'); +testFile('test/t/cases/typedeftag.js'); testFile('test/t/cases/variations.js'); testFile('test/t/cases/versiontag.js'); diff --git a/test/t/cases/typedeftag.js b/test/t/cases/typedeftag.js new file mode 100644 index 00000000..1728c4cc --- /dev/null +++ b/test/t/cases/typedeftag.js @@ -0,0 +1,24 @@ +(function() { + var docSet = testhelpers.getDocSetFromFile('test/cases/typedeftag.js'), + numberlike = docSet.getByLongname('calc.NumberLike')[0]; + + //dump(docSet.doclets); exit(0); + + test('When a symbol has an @typedef tag, the doclet has a kind property set to "typedef".', function() { + assert.equal(numberlike.kind, 'typedef'); + }); + + test('When a symbol has an @typedef tag with a type, the doclet has a type property set to that type.', function() { + assert.equal(typeof numberlike.type, 'object'); + assert.equal(typeof numberlike.type.names, 'object'); + assert.equal(numberlike.type.names.length, 2); + assert.equal(numberlike.type.names[0], 'string'); + assert.equal(numberlike.type.names[1], 'number'); + }); + + test('When a symbol has an @typedef tag with a name, the doclet has a name property set to that name.', function() { + assert.equal(numberlike.name, 'NumberLike'); + assert.equal(numberlike.longname, 'calc.NumberLike'); + }); + +})(); \ No newline at end of file From e4852bcb159fe4c6e844dc1c3a0f8fb235f0f7ea Mon Sep 17 00:00:00 2001 From: Michael Mathews Date: Thu, 10 Feb 2011 23:23:12 +0000 Subject: [PATCH 5/9] Improved detection of outer/inner scoped variables. --- modules/jsdoc/doclet.js | 6 +++ modules/jsdoc/name.js | 9 ++++ modules/jsdoc/src/parser.js | 87 +++++++++++++++++++++++++++++-------- test/cases/innerscope.js | 14 ++++++ test/cases/innerscope2.js | 16 +++++++ test/cases/this.js | 1 - test/cases/this2.js | 4 +- test/runner.js | 2 + test/t/cases/innerscope.js | 15 +++++++ test/t/cases/innerscope2.js | 11 +++++ test/t/cases/this.js | 2 +- 11 files changed, 145 insertions(+), 22 deletions(-) create mode 100644 test/cases/innerscope.js create mode 100644 test/cases/innerscope2.js create mode 100644 test/t/cases/innerscope.js create mode 100644 test/t/cases/innerscope2.js diff --git a/modules/jsdoc/doclet.js b/modules/jsdoc/doclet.js index 28fdd651..94ce356e 100644 --- a/modules/jsdoc/doclet.js +++ b/modules/jsdoc/doclet.js @@ -160,6 +160,12 @@ /** The type of the symbol in the source code. */ this.meta.code.type = meta.code.type; } + if (meta.code.node) { + this.meta.code.node = meta.code.node; + } + if (meta.code.funcscope) { + this.meta.code.funcscope = meta.code.funcscope; + } if (meta.code.value) { /** The value of the symbol in the source code. */ this.meta.code.value = meta.code.value; diff --git a/modules/jsdoc/name.js b/modules/jsdoc/name.js index ac4ced0d..324b9634 100644 --- a/modules/jsdoc/name.js +++ b/modules/jsdoc/name.js @@ -47,6 +47,15 @@ doclet.name = about.name; } + if (doclet.name && !memberof) { + if (doclet.meta.code && doclet.meta.code.funcscope) { + about.memberof = doclet.meta.code.funcscope; + doclet.longname = about.memberof + '~' + name; + about.scope = '~'; + } + + } + if (about.memberof) { doclet.setMemberof(about.memberof); } diff --git a/modules/jsdoc/src/parser.js b/modules/jsdoc/src/parser.js index 246b94dc..47eb765c 100644 --- a/modules/jsdoc/src/parser.js +++ b/modules/jsdoc/src/parser.js @@ -125,7 +125,7 @@ memberof.id = 'astnode'+astnode.enclosingFunction.hashCode(); memberof.doclet = this.refs[memberof.id]; if (!memberof.doclet) { - return '[[anonymous]]~'; + return '~'; } return (memberof.doclet.longname||memberof.doclet.name) + '~'; } @@ -138,7 +138,6 @@ } } - /** Resolve what "this" refers too, relative to a node */ @@ -150,7 +149,7 @@ memberof.doclet = this.refs[memberof.id]; if (!memberof.doclet) { - return '[[anonymous]]'; // TODO handle global this? + return ''; // TODO handle global this? } if (memberof.doclet['this']) { @@ -165,15 +164,13 @@ return memberof.doclet.longname||memberof.doclet.name; } else { - if (memberof.doclet.meta.code.val){ - return this.resolveThis(memberof.doclet.meta.code.val); + if (astnode.enclosingFunction){ + return this.resolveThis(astnode.enclosingFunction/*memberof.doclet.meta.code.val*/); } else return ''; // TODO handle global this? } } else if (astnode.parent) { - //print('member of something that isnt a function? '+'astnode'+astnode.parent.parent.hashCode()+' ('+nodeToString(astnode.parent.parent)+')'); - var parent = astnode.parent; if (parent.type === Token.COLON) parent = parent.parent; // go up one more @@ -189,6 +186,37 @@ } } + /** + Resolve what function a var is limited to. + @param {astnode} node + @param {string} basename The leftmost name in the long name: in foo.bar.zip the basename is foo. + */ + Parser.prototype.resolveVar = function(node, basename) { + var memberof = {}; + + if (node.enclosingFunction) { + memberof.id = 'astnode'+node.enclosingFunction.hashCode(); + memberof.doclet = this.refs[memberof.id]; + + if (!memberof.doclet) { + return this.resolveVar(node.enclosingFunction, basename); + } + + if (memberof.doclet.vars && ~memberof.doclet.vars.indexOf(basename) ) { + return memberof.doclet.longname; + } + else { + if (memberof.doclet.meta.code.node){ + return this.resolveVar(memberof.doclet.meta.code.node, basename); + } + else return ''; // TODO handle global this? + } + } + else { + return ''; // global? + } + } + /** @private */ @@ -228,12 +256,15 @@ code: aboutNode(node) }; + var basename = e.code.name.replace(/^([$a-z_][$a-z_0-9]*).*?$/i, '$1'); + if (basename !== 'this') e.code.funcscope = currentParser.resolveVar(node, basename); + if ( isValidJsdoc(e.comment) ) { currentParser.fire('symbolFound', e, currentParser); } if (e.doclet) { - currentParser.refs['astnode'+e.code.val.hashCode()] = e.doclet; // allow lookup from value => doclet + currentParser.refs['astnode'+e.code.node.hashCode()] = e.doclet; // allow lookup from value => doclet } } else if (node.type === Token.COLON) { @@ -251,7 +282,7 @@ } if (e.doclet) { - currentParser.refs['astnode'+e.code.val.hashCode()] = e.doclet; // allow lookup from value => doclet + currentParser.refs['astnode'+e.code.node.hashCode()] = e.doclet; // allow lookup from value => doclet } } else if (node.type == Token.VAR || node.type == Token.LET || node.type == Token.CONST) { @@ -274,12 +305,23 @@ code: aboutNode(node) }; + // keep track of vars in a function scope + if (node.enclosingFunction) { + var func = 'astnode'+node.enclosingFunction.hashCode(), + funcDoc = currentParser.refs[func]; + + if (funcDoc) { + funcDoc.vars = func.vars || []; + funcDoc.vars.push(e.code.name); + } + } + if ( isValidJsdoc(e.comment) ) { currentParser.fire('symbolFound', e, currentParser); } if (e.doclet) { - currentParser.refs['astnode'+e.code.val.hashCode()] = e.doclet; // allow lookup from value => doclet + currentParser.refs['astnode'+e.code.node.hashCode()] = e.doclet; // allow lookup from value => doclet } } else if (node.type == Token.FUNCTION/* && String(node.name) !== ''*/) { @@ -297,9 +339,17 @@ if ( isValidJsdoc(e.comment) ) { currentParser.fire('symbolFound', e, currentParser); } - + if (e.doclet) { - currentParser.refs['astnode'+node.hashCode()] = e.doclet; // allow lookup from value => doclet +//dump(e.code.node.hashCode(), e.code, e.code.node.enclosingFunction? e.code.node.enclosingFunction.hashCode() : 'global') + currentParser.refs['astnode'+e.code.node.hashCode()] = e.doclet; // allow lookup from value => doclet + } + else if (!currentParser.refs['astnode'+e.code.node.hashCode()]) { // keep references to undocumented anonymous functions too as they might have scoped vars + currentParser.refs['astnode'+e.code.node.hashCode()] = { + //name: '', + longname: '', + meta: { code: e.code } + }; } } @@ -331,6 +381,7 @@ if (node.type == Token.FUNCTION /*&& String(node.name) !== ''*/) { about.name = '' + node.name; about.type = 'function'; + about.node = node; return about; } @@ -338,13 +389,13 @@ if (node.type == Token.VAR || node.type == Token.LET || node.type == Token.CONST) { about.name = nodeToString(node.target); if (node.initializer) { // like var i = 0; - about.val = node.initializer; - about.value = nodeToString(about.val); + about.node = node.initializer; + about.value = nodeToString(about.node); about.type = getTypeName(node.initializer); } else { // like var i; - about.val = node.target; - about.value = nodeToString(about.val); + about.node = node.target; + about.value = nodeToString(about.node); about.type = 'undefined'; } @@ -353,8 +404,8 @@ if (node.type === Token.ASSIGN || node.type === Token.COLON) { about.name = nodeToString(node.left); - about.val = node.right; - about.value = nodeToString(about.val); + about.node = node.right; + about.value = nodeToString(about.node); about.type = getTypeName(node.right); return about; } diff --git a/test/cases/innerscope.js b/test/cases/innerscope.js new file mode 100644 index 00000000..6a623f34 --- /dev/null +++ b/test/cases/innerscope.js @@ -0,0 +1,14 @@ +/** @constructor */ +function Message(to) { + + var headers = {}; + + /** document me */ + headers.to = to; + + (function() { + /** document me */ + headers.from = ''; + })() +} + diff --git a/test/cases/innerscope2.js b/test/cases/innerscope2.js new file mode 100644 index 00000000..791bcf37 --- /dev/null +++ b/test/cases/innerscope2.js @@ -0,0 +1,16 @@ +/** @constructor */ +function Message(to) { + + var headers = {}; + + /** document me */ + headers.to = to; + + (function() { + var headers = {}; + + /** document me */ + headers.from = ''; + })() +} + diff --git a/test/cases/this.js b/test/cases/this.js index ff76fdf4..7c167606 100644 --- a/test/cases/this.js +++ b/test/cases/this.js @@ -7,5 +7,4 @@ function Singer() { /** document me */ this.isSinging = true; // setting a member of constructor Singer }; - } \ No newline at end of file diff --git a/test/cases/this2.js b/test/cases/this2.js index 640eb917..88fd9fa6 100644 --- a/test/cases/this2.js +++ b/test/cases/this2.js @@ -1,7 +1,7 @@ /** @constructor */ function TemplateBuilder(templateType) { - /** document me */ - this.templateType = templateType; + //** document me */ + //this.templateType = templateType; /** @constructor */ this.Template = function() { // nested constructor of constructor TemplateFactory diff --git a/test/runner.js b/test/runner.js index 4a36488f..d17dfead 100644 --- a/test/runner.js +++ b/test/runner.js @@ -82,6 +82,8 @@ testFile('test/t/cases/this-and-objectlit.js'); testFile('test/t/cases/var.js'); testFile('test/t/cases/inner.js'); +testFile('test/t/cases/innerscope.js'); +testFile('test/t/cases/innerscope2.js'); testFile('test/t/cases/modules/data/mod-1.js'); testFile('test/t/cases/modules/data/mod-2.js'); diff --git a/test/t/cases/innerscope.js b/test/t/cases/innerscope.js new file mode 100644 index 00000000..df8ef3ce --- /dev/null +++ b/test/t/cases/innerscope.js @@ -0,0 +1,15 @@ +(function() { + var docSet = testhelpers.getDocSetFromFile('test/cases/innerscope.js'), + to = docSet.getByLongname('Message~headers.to'), + from = docSet.getByLongname('Message~headers.from'); + + //dump(docSet); + + test('When a member of a var member is documented.', function() { + assert.equal(to.length, 1, 'It is like Outer~inner.member.'); + }); + + test('When a deeply nested member of a var member is documented.', function() { + assert.equal(from.length, 1, 'It is still like Outer~inner.member.'); + }); +})(); \ No newline at end of file diff --git a/test/t/cases/innerscope2.js b/test/t/cases/innerscope2.js new file mode 100644 index 00000000..c13e2aa3 --- /dev/null +++ b/test/t/cases/innerscope2.js @@ -0,0 +1,11 @@ +(function() { + var docSet = testhelpers.getDocSetFromFile('test/cases/innerscope2.js'), + to = docSet.getByLongname('Message~headers.to'), + from = docSet.getByLongname('~headers.from'); + + //dump(docSet); + + test('When a var is masked by an inner var and a member of the inner is documented.', function() { + assert.equal(from.length, 1, 'It is still like Inner~inner.member.'); + }); +})(); \ No newline at end of file diff --git a/test/t/cases/this.js b/test/t/cases/this.js index 8e9a9b9c..212907da 100644 --- a/test/t/cases/this.js +++ b/test/t/cases/this.js @@ -3,7 +3,7 @@ found1 = docSet.getByLongname('Singer#tralala'), found2 = docSet.getByLongname('Singer#isSinging'); - //dump(docSet); + // dump(docSet); test('When a member is attached to this in a constructor.', function() { assert.equal(found1.length, 1, 'The longname should be like Constructor#member.'); From d36955ccf8884a0e2ee57f0ecbf44d8f3b2e339c Mon Sep 17 00:00:00 2001 From: Michael Mathews Date: Fri, 11 Feb 2011 21:12:53 +0000 Subject: [PATCH 6/9] Refactor of var scope code. --- modules/jsdoc/name.js | 14 ++++----- modules/jsdoc/src/parser.js | 60 +++++++++++++++---------------------- test/cases/innerscope2.js | 5 +++- test/t/cases/innerscope2.js | 14 +++++++-- 4 files changed, 46 insertions(+), 47 deletions(-) diff --git a/modules/jsdoc/name.js b/modules/jsdoc/name.js index 324b9634..9eca76ca 100644 --- a/modules/jsdoc/name.js +++ b/modules/jsdoc/name.js @@ -25,6 +25,11 @@ name = name? (''+name).replace(/\.prototype\.?/g, '#') : ''; + // member of a var in an outer scope? + if (name && !memberof && doclet.meta.code && doclet.meta.code.funcscope) { + name = doclet.longname = doclet.meta.code.funcscope + '~' + name; + } + if (memberof) { // @memberof tag given memberof = memberof.replace(/\.prototype\.?/g, '#'); @@ -47,14 +52,7 @@ doclet.name = about.name; } - if (doclet.name && !memberof) { - if (doclet.meta.code && doclet.meta.code.funcscope) { - about.memberof = doclet.meta.code.funcscope; - doclet.longname = about.memberof + '~' + name; - about.scope = '~'; - } - - } + if (about.memberof) { doclet.setMemberof(about.memberof); diff --git a/modules/jsdoc/src/parser.js b/modules/jsdoc/src/parser.js index 47eb765c..6661e233 100644 --- a/modules/jsdoc/src/parser.js +++ b/modules/jsdoc/src/parser.js @@ -30,7 +30,7 @@ @fires fileBegin @fires fileComplete */ - Parser.prototype.parse = function(sourceFiles, encoding) { + exports.Parser.prototype.parse = function(sourceFiles, encoding) { const SCHEMA = 'javascript:'; var sourceCode = '', filename = ''; @@ -56,7 +56,6 @@ currentParser = this; this._parseSourceCode(sourceCode, filename); currentParser = null; - pragmas = {}; // always resets at end of file } return this._resultBuffer; @@ -66,14 +65,14 @@ @method module:jsdoc/src/parser.Parser#results @returns {Array} The accumulated results of any calls to parse. */ - Parser.prototype.results = function() { + exports.Parser.prototype.results = function() { return this._resultBuffer; } /** @method module:jsdoc/src/parser.Parser#addResult */ - Parser.prototype.addResult = function(o) { + exports.Parser.prototype.addResult = function(o) { this._resultBuffer.push(o); } @@ -81,7 +80,7 @@ Empty any accumulated results of calls to parse. @method module:jsdoc/src/parser.Parser#clear */ - Parser.prototype.clear = function() { + exports.Parser.prototype.clear = function() { currentParser = null; currentSourceName = ''; this._resultBuffer = []; @@ -90,7 +89,7 @@ /** @private */ - Parser.prototype._parseSourceCode = function(sourceCode, sourceName) { + exports.Parser.prototype._parseSourceCode = function(sourceCode, sourceName) { currentSourceName = sourceName; // merge adjacent doclets @@ -117,7 +116,7 @@ /** Given a node, determine what the node is a member of. */ - Parser.prototype.astnodeToMemberof = function(astnode) { + exports.Parser.prototype.astnodeToMemberof = function(astnode) { var memberof = {}; if (astnode.type === Token.VAR || astnode.type === Token.FUNCTION) { @@ -141,11 +140,11 @@ /** Resolve what "this" refers too, relative to a node */ - Parser.prototype.resolveThis = function(astnode) { + exports.Parser.prototype.resolveThis = function(node) { var memberof = {}; - if (astnode.enclosingFunction) { - memberof.id = 'astnode'+astnode.enclosingFunction.hashCode(); + if (node.enclosingFunction) { + memberof.id = 'astnode'+node.enclosingFunction.hashCode(); memberof.doclet = this.refs[memberof.id]; if (!memberof.doclet) { @@ -164,14 +163,14 @@ return memberof.doclet.longname||memberof.doclet.name; } else { - if (astnode.enclosingFunction){ - return this.resolveThis(astnode.enclosingFunction/*memberof.doclet.meta.code.val*/); + if (node.enclosingFunction){ + return this.resolveThis(node.enclosingFunction/*memberof.doclet.meta.code.val*/); } else return ''; // TODO handle global this? } } - else if (astnode.parent) { - var parent = astnode.parent; + else if (node.parent) { + var parent = node.parent; if (parent.type === Token.COLON) parent = parent.parent; // go up one more memberof.id = 'astnode'+parent.hashCode(); @@ -191,30 +190,19 @@ @param {astnode} node @param {string} basename The leftmost name in the long name: in foo.bar.zip the basename is foo. */ - Parser.prototype.resolveVar = function(node, basename) { - var memberof = {}; + exports.Parser.prototype.resolveVar = function(node, basename) { + var doclet, + enclosingFunction = node.enclosingFunction; - if (node.enclosingFunction) { - memberof.id = 'astnode'+node.enclosingFunction.hashCode(); - memberof.doclet = this.refs[memberof.id]; - - if (!memberof.doclet) { - return this.resolveVar(node.enclosingFunction, basename); - } - - if (memberof.doclet.vars && ~memberof.doclet.vars.indexOf(basename) ) { - return memberof.doclet.longname; - } - else { - if (memberof.doclet.meta.code.node){ - return this.resolveVar(memberof.doclet.meta.code.node, basename); - } - else return ''; // TODO handle global this? - } - } - else { - return ''; // global? + if (!enclosingFunction) { return ''; } // global + + doclet = this.refs['astnode'+enclosingFunction.hashCode()]; + + if ( doclet && doclet.vars && ~doclet.vars.indexOf(basename) ) { + return doclet.longname; } + + return this.resolveVar(enclosingFunction, basename); } /** diff --git a/test/cases/innerscope2.js b/test/cases/innerscope2.js index 791bcf37..68f30cba 100644 --- a/test/cases/innerscope2.js +++ b/test/cases/innerscope2.js @@ -7,7 +7,10 @@ function Message(to) { headers.to = to; (function() { - var headers = {}; + var headers = { + /** document me */ + cache: {} + }; /** document me */ headers.from = ''; diff --git a/test/t/cases/innerscope2.js b/test/t/cases/innerscope2.js index c13e2aa3..c29516ac 100644 --- a/test/t/cases/innerscope2.js +++ b/test/t/cases/innerscope2.js @@ -1,11 +1,21 @@ (function() { var docSet = testhelpers.getDocSetFromFile('test/cases/innerscope2.js'), to = docSet.getByLongname('Message~headers.to'), - from = docSet.getByLongname('~headers.from'); + from = docSet.getByLongname('~headers.from'), + cache = docSet.getByLongname('~headers.cache'); //dump(docSet); + test('When a var is declared in a function.', function() { + assert.equal(cache.length, 1, 'It is like Inner~member.'); + }); + test('When a var is masked by an inner var and a member of the inner is documented.', function() { - assert.equal(from.length, 1, 'It is still like Inner~inner.member.'); + assert.equal(from.length, 1, 'It is like Inner~inner.member.'); + }); + + test('When a documented member is assigned to a var that masks an outer var.', function() { + assert.equal(from[0].name, 'from'); + assert.equal(from[0].memberof, '~headers'); }); })(); \ No newline at end of file From 61e74dcd5fd6013ffeed5621d138c59e385ddec7 Mon Sep 17 00:00:00 2001 From: Michael Mathews Date: Sun, 13 Feb 2011 00:18:09 +0000 Subject: [PATCH 7/9] Fixed up default template more, added static files. --- modules/common/fs.js | 41 ++- modules/jsdoc/src/parser.js | 102 ++++---- package.json | 2 +- templates/default/publish.js | 13 + .../default/static/styles/jsdoc-default.css | 233 +++++++++++++++++ templates/default/static/styles/node-dark.css | 26 ++ templates/default/tmpl/container.mustache | 244 +----------------- templates/default/tmpl/example.mustache | 12 + templates/default/tmpl/methods.mustache | 6 +- templates/default/tmpl/properties.mustache | 15 +- 10 files changed, 387 insertions(+), 307 deletions(-) create mode 100644 templates/default/static/styles/jsdoc-default.css create mode 100644 templates/default/static/styles/node-dark.css create mode 100644 templates/default/tmpl/example.mustache diff --git a/modules/common/fs.js b/modules/common/fs.js index b749c99d..851d4aac 100644 --- a/modules/common/fs.js +++ b/modules/common/fs.js @@ -106,6 +106,42 @@ return _allFiles; } + exports.copyFile = function(inFile, outDir, fileName) { + if (fileName == null) fileName = exports.toFile(inFile); + + outDir = exports.toDir(outDir); + + var inFile = new File(inFile); + var outFile = new File(outDir+slash+fileName); + + var bis = new Packages.java.io.BufferedInputStream(new Packages.java.io.FileInputStream(inFile), 4096); + var bos = new Packages.java.io.BufferedOutputStream(new Packages.java.io.FileOutputStream(outFile), 4096); + var theChar; + while ((theChar = bis.read()) != -1) { + bos.write(theChar); + } + bos.close(); + bis.close(); + } + + exports.toDir = function(path) { + var file = new File(path); + + if (file.isDirectory()){ + return path; + } + + var parts = path.split(/[\\\/]/); + parts.pop(); + + return parts.join(slash); + } + + exports.toFile = function(path) { + var parts = path.split(/[\\\/]/); + return parts.pop(); + } + exports.mkPath = function(/**Array*/ path) { if (path.constructor != Array) path = path.split(/[\\\/]/); var make = ""; @@ -118,8 +154,9 @@ } exports.makeDir = function(/**string*/ path) { - (new File(path)).mkdir(); - }, + var dirPath = (exports.toDir(path)); + (new File(dirPath)).mkdir(); + } // fix multiple slashes, like one//two function fixSlash(path) { diff --git a/modules/jsdoc/src/parser.js b/modules/jsdoc/src/parser.js index 6661e233..a30f75c7 100644 --- a/modules/jsdoc/src/parser.js +++ b/modules/jsdoc/src/parser.js @@ -1,8 +1,8 @@ /** - @module jsdoc/src/parser - @requires module:common/util - @requires module:common/fs - @requires module:common/events + * @module jsdoc/src/parser + * @requires common/util + * @requires common/fs + * @requires common/events */ (function() { @@ -11,24 +11,31 @@ currentSourceName = ''; /** - @constructor module:jsdoc/src/parser.Parser - @mixes module:common/events + * @class + * @mixes module:common/events + * + * @example + * var jsdocParser = new (require('jsdoc/src/parser').Parser)(); */ - var Parser = exports.Parser = function() { + exports.Parser = function() { this._resultBuffer = []; this.refs = {}; } - require('common/util').mixin(Parser.prototype, require('common/events')); + require('common/util').mixin(exports.Parser.prototype, require('common/events')); /** - @method module:jsdoc/src/parser.Parser#parse - @param {Array} sourceFiles - @param {string} [encoding=utf8] - @fires jsdocCommentFound - @fires symbolFound - @fires newDoclet - @fires fileBegin - @fires fileComplete + * @param {Array} sourceFiles + * @param {string} [encoding=utf8] + * + * @fires jsdocCommentFound + * @fires symbolFound + * @fires newDoclet + * @fires fileBegin + * @fires fileComplete + * + * @example + * var myFiles = ['file1.js', 'file2.js']; + * var docs = jsdocParser.parse(myFiles); */ exports.Parser.prototype.parse = function(sourceFiles, encoding) { const SCHEMA = 'javascript:'; @@ -62,23 +69,21 @@ } /** - @method module:jsdoc/src/parser.Parser#results - @returns {Array} The accumulated results of any calls to parse. + * @returns {Array} The accumulated results of any calls to parse. */ exports.Parser.prototype.results = function() { return this._resultBuffer; } /** - @method module:jsdoc/src/parser.Parser#addResult + * @param {Object} The parse result to add to the result buffer. */ exports.Parser.prototype.addResult = function(o) { this._resultBuffer.push(o); } /** - Empty any accumulated results of calls to parse. - @method module:jsdoc/src/parser.Parser#clear + * Empty any accumulated results of calls to parse. */ exports.Parser.prototype.clear = function() { currentParser = null; @@ -86,9 +91,7 @@ this._resultBuffer = []; } - /** - @private - */ + /** @private */ exports.Parser.prototype._parseSourceCode = function(sourceCode, sourceName) { currentSourceName = sourceName; @@ -114,14 +117,15 @@ } /** - Given a node, determine what the node is a member of. + * Given a node, determine what the node is a member of. + * @param {astnode} node */ - exports.Parser.prototype.astnodeToMemberof = function(astnode) { + exports.Parser.prototype.astnodeToMemberof = function(node) { var memberof = {}; - if (astnode.type === Token.VAR || astnode.type === Token.FUNCTION) { - if (astnode.enclosingFunction) { // an inner var or func - memberof.id = 'astnode'+astnode.enclosingFunction.hashCode(); + if (node.type === Token.VAR || node.type === Token.FUNCTION) { + if (node.enclosingFunction) { // an inner var or func + memberof.id = 'astnode'+node.enclosingFunction.hashCode(); memberof.doclet = this.refs[memberof.id]; if (!memberof.doclet) { return '~'; @@ -130,7 +134,7 @@ } } else { - memberof.id = 'astnode'+astnode.parent.hashCode(); + memberof.id = 'astnode'+node.parent.hashCode(); memberof.doclet = this.refs[memberof.id]; if (!memberof.doclet) return ''; // global? return memberof.doclet.longname||memberof.doclet.name; @@ -138,7 +142,9 @@ } /** - Resolve what "this" refers too, relative to a node + * Resolve what "this" refers too, relative to a node. + * @param {astnode} node - The "this" node + * @returns {string} The longname of the enclosing node. */ exports.Parser.prototype.resolveThis = function(node) { var memberof = {}; @@ -186,9 +192,9 @@ } /** - Resolve what function a var is limited to. - @param {astnode} node - @param {string} basename The leftmost name in the long name: in foo.bar.zip the basename is foo. + * Resolve what function a var is limited to. + * @param {astnode} node + * @param {string} basename The leftmost name in the long name: in foo.bar.zip the basename is foo. */ exports.Parser.prototype.resolveVar = function(node, basename) { var doclet, @@ -205,9 +211,7 @@ return this.resolveVar(enclosingFunction, basename); } - /** - @private - */ + /** @private */ function visitNode(node) { var e, commentSrc; @@ -312,7 +316,7 @@ currentParser.refs['astnode'+e.code.node.hashCode()] = e.doclet; // allow lookup from value => doclet } } - else if (node.type == Token.FUNCTION/* && String(node.name) !== ''*/) { + else if (node.type == Token.FUNCTION) { e = { id: 'astnode'+node.hashCode(), // the id of the COLON node comment: String(node.jsDoc||'@undocumented'), @@ -329,12 +333,10 @@ } if (e.doclet) { -//dump(e.code.node.hashCode(), e.code, e.code.node.enclosingFunction? e.code.node.enclosingFunction.hashCode() : 'global') currentParser.refs['astnode'+e.code.node.hashCode()] = e.doclet; // allow lookup from value => doclet } else if (!currentParser.refs['astnode'+e.code.node.hashCode()]) { // keep references to undocumented anonymous functions too as they might have scoped vars currentParser.refs['astnode'+e.code.node.hashCode()] = { - //name: '', longname: '', meta: { code: e.code } }; @@ -344,9 +346,7 @@ return true; } - /** - @private - */ + /** @private */ function parserFactory() { var cx = Packages.org.mozilla.javascript.Context.getCurrentContext(); @@ -360,8 +360,8 @@ } /** - Attempts to find the name and type of the given node. - @private + * Attempts to find the name and type of the given node. + * @private */ function aboutNode(node) { about = {}; @@ -408,9 +408,7 @@ return about; } - /** - @private - */ + /** @private */ function nodeToString(node) { var str; @@ -444,9 +442,7 @@ return '' + str; }; - /** - @private - */ + /** @private */ function getTypeName(node) { var type = ''; @@ -457,9 +453,7 @@ return type; } - /** - @private - */ + /** @private */ function isValidJsdoc(commentSrc) { return commentSrc.indexOf('/***') !== 0; /*** ignore comments that start with many stars ***/ } diff --git a/package.json b/package.json index 9547be1e..ae59bd47 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "jsdoc", "version": "3.0.0beta1", - "revision": "2011-02-08-2004", + "revision": "2011-02-11-2113", "description": "An automatic documentation generator for javascript.", "keywords": [ "documentation", "javascript" ], "licenses": [ diff --git a/templates/default/publish.js b/templates/default/publish.js index 87347a80..cc322ce7 100644 --- a/templates/default/publish.js +++ b/templates/default/publish.js @@ -53,6 +53,7 @@ doclet.hasReturns = doclet.returns && doclet.returns.length > 0; doclet.hasBorrowed = doclet.borrowed && doclet.borrowed.length > 0; doclet.hasExceptions = doclet.exceptions && doclet.exceptions.length > 0; + doclet.hasExamples = doclet.examples && doclet.examples.length > 0; summarize(doclet); }); @@ -65,6 +66,7 @@ returnsTemplate: fs.read(BASEDIR + 'templates/default/tmpl/returns.mustache'), methodsTemplate: fs.read(BASEDIR + 'templates/default/tmpl/methods.mustache'), propertiesTemplate: fs.read(BASEDIR + 'templates/default/tmpl/properties.mustache'), + examplesTemplate: fs.read(BASEDIR + 'templates/default/tmpl/example.mustache'), namespacesTemplate: fs.read(BASEDIR + 'templates/default/tmpl/namespaces.mustache'), classesTemplate: fs.read(BASEDIR + 'templates/default/tmpl/classes.mustache'), @@ -167,6 +169,17 @@ } fs.mkPath(outdir); + // copy static files to outdir + var fromDir = BASEDIR + 'templates/default/static', + staticFiles = fs.ls(fromDir, 3); + staticFiles.forEach(function(fileName) { + var toDir = fs.toDir(fileName.replace(fromDir, outdir)); + fs.mkPath(toDir); + fs.copyFile(fileName, toDir); + }); + + + // containers generate('Modules', modules, 'modules.html'); generate('Classes', classes, 'classes.html'); diff --git a/templates/default/static/styles/jsdoc-default.css b/templates/default/static/styles/jsdoc-default.css new file mode 100644 index 00000000..0cf7841f --- /dev/null +++ b/templates/default/static/styles/jsdoc-default.css @@ -0,0 +1,233 @@ +.kind { font-style: italic; } + +.constructor, .mixin, .namespace +{ + font-weight: bold; + color: #780000; +} + +.property { color: #666; } +.function { color: #666; } +.access { color: #666; } + +h1, h2, h3, h4, h5, h6 +{ + font-family: "Bitstream Vera Sans", "DejaVu Sans", "Trebuchet MS", Verdana, "Verdana Ref", sans serif; + font-weight: bold; +} + +.page-title +{ + font-family: "Bitstream Vera Sans", "DejaVu Sans", "Trebuchet MS", Verdana, "Verdana Ref", sans serif; + font-size: 3.5em; + font-weight: bolder; + margin: 0 0 0.1em; + color: #FFF; +} + +.section-title +{ + font-size: 2.5em; + margin: 0; + color: #798D3E; +} + +section +{ + border: 1px solid #ccc; + border-radius: 15px; + -moz-border-radius: 8px; + display: block; + padding: 0.75em 0.5em 0.5em 1em; + margin: 0.5em 0.5em 1em 1em; + background-color: #fff; + color: #000; +} + +.subsection-title +{ + font-size: 1.9em; + margin: 0.5em 0 1em; + color: #000; +} + +.method-title, .class-title +{ + font-size: 1.7em; + margin: 0 0 1em 1em; + color: #7B1A3F; +} + +.detail-list { list-style-type: none; } + +html +{ + /* stops IE resizing fonts by a massive amount */ + font-size: 100%; +} + +body +{ + /* fixes monospace font sizes in webkit */ + /* following line is picked up by IE6 & 7, which cannot resize pixel-based font sizes */ + *font-size: 62.5%; + font-size: 0.8em; + font-family: verdana, sans-serif; + /*overflow: hidden;*/ + zoom: 1; + /*background: url(images/pagebg.png) 0 73px repeat-x;*/ + color: #eee; + background-color: #22252a; +} + +a:link, a:visited +{ + color: #356a8b; + text-decoration: none; + border-bottom: 1px dotted #356a8b; +} + +a:hover, a:active +{ + color: #298FB2; + border-color: #298FB2; + border-bottom-style: solid; +} + +a.image { border: 0; } + +p +{ + margin: 0 0 1em 0; + line-height: 1.5; +} + +code { font-family: Consolas, "Andale Mono WT", "Andale Mono", "Lucida Console", "Lucida Sans Typewriter", "DejaVu Sans Mono", "Bitstream Vera Sans Mono", "Liberation Mono", "Nimbus Mono L", Monaco, "Courier New", Courier, monospace; } + +dl.params dt +{ + border-top: 1px solid #b2b1b1; + color: #298FB2; + font-weight: bold; + padding-top: 8px; + margin-bottom: 5px; + font-size: 1.1em; + float: none; + overflow: visible; + zoom: 0; +} + +dl.params dt.first +{ + border-top: none; + padding-top: 0; + margin-top: 0; +} + +dl.params dd +{ + border-width: 0; + margin-bottom: 16px; +} + +dl.param-properties +{ + font-style: italic; + overflow: hidden; + zoom: 1; + font-size: 0.9em; + margin: 1em 0; +} + +dl.param-properties dt span, +dl.param-properties dd +{ + color: #555; + float: left; + margin: 0; + padding: 0; + display: inline; + margin-bottom: 5px; + font-size: 1em; + border: none; +} + +dl.param-properties dt +{ + clear: both; + display: inline; + font-size: 1em; + padding: 0; + float: none; + overflow: visible; + zoom: 0; +} + +dl.param-properties dt span +{ + width: 85px; + clear: both; +} + +.no-docs +{ + font-style: italic; + font-weight: lighter; + color: #666; +} + +.property { margin-left: 30px; } + +.property-head +{ + margin-left: -20px; + display: block; + line-height: 1.2em; +} + +.property-name +{ + float: left; + margin: 0; + padding: 0 10px 0 0; + font-style: italic; + font-weight: bold; + font-size: 1.2em; + color: #4782B5; +} + +.property-summary +{ + color: #999; + font-size: 1em; +} + +.property-details +{ + clear: both; + overflow: hidden; +} + +.property-details dt +{ + font-weight: bold; + margin-bottom: 4px; + padding-left: 10px; + clear: left; + float: left; +} + +.property-details dd { padding-left: 60px; } +.property-deprecated { text-decoration: line-through; } + +.example-code +{ + padding: 2px 2px 2px 10px; + margin-right: 24px; + color: #fff; + background-color: #444; + border-radius: 2px; + -moz-border-radius: 2px; +} + +.yesDef { text-indent: -5000px; } \ No newline at end of file diff --git a/templates/default/static/styles/node-dark.css b/templates/default/static/styles/node-dark.css new file mode 100644 index 00000000..234e127d --- /dev/null +++ b/templates/default/static/styles/node-dark.css @@ -0,0 +1,26 @@ +.sh_sourceCode { + + font-weight: normal; + font-style: normal; +} + +.sh_sourceCode .sh_symbol , .sh_sourceCode .sh_cbracket { + color: #fff; +} + +.sh_sourceCode .sh_keyword +{ + font-style: italic; + color: #ECDDAA; +} + +.sh_sourceCode .sh_string, .sh_sourceCode .sh_regexp, .sh_sourceCode .sh_number, +.sh_sourceCode .sh_specialchar +{ + color: #B0C4DE; +} + +.sh_sourceCode .sh_comment { + color: #777; +} + diff --git a/templates/default/tmpl/container.mustache b/templates/default/tmpl/container.mustache index b1b7218d..34692572 100644 --- a/templates/default/tmpl/container.mustache +++ b/templates/default/tmpl/container.mustache @@ -4,244 +4,13 @@ JSDoc: {{title}} - + @@ -308,5 +77,6 @@ {{/docs}} + \ No newline at end of file diff --git a/templates/default/tmpl/example.mustache b/templates/default/tmpl/example.mustache new file mode 100644 index 00000000..089ac843 --- /dev/null +++ b/templates/default/tmpl/example.mustache @@ -0,0 +1,12 @@ +
+
Example
+
+
+ {{#examples}} +
+
+
{{.}}
+
+
+ {{/examples}} +
diff --git a/templates/default/tmpl/methods.mustache b/templates/default/tmpl/methods.mustache index 058a8e76..b7e621b8 100644 --- a/templates/default/tmpl/methods.mustache +++ b/templates/default/tmpl/methods.mustache @@ -8,7 +8,7 @@
Synopsis:
-
{{synopsis}}
+
{{synopsis}}
{{#hasParams}}
Parameters:
@@ -24,6 +24,10 @@
Returns:
{{>returnsTemplate}} {{/hasReturns}} + + {{#hasExamples}} + {{>examplesTemplate}} + {{/hasExamples}}
diff --git a/templates/default/tmpl/properties.mustache b/templates/default/tmpl/properties.mustache index e3763428..341b5384 100644 --- a/templates/default/tmpl/properties.mustache +++ b/templates/default/tmpl/properties.mustache @@ -81,17 +81,8 @@ {{/defaultvalue}} - {{#examples}} -
- Example -
-
-
-
-
{{.}}
-
-
-
- {{/examples}} + {{#hasExamples}} + {{>examplesTemplate}} + {{/hasExamples}
\ No newline at end of file From 10a71c6b4ba650fff58c8c444cd667217ed5e9b0 Mon Sep 17 00:00:00 2001 From: Michael Mathews Date: Tue, 22 Feb 2011 09:44:50 +0000 Subject: [PATCH 8/9] Fixes for var scoping, @lends and @borrows. --- modules/jsdoc/doclet.js | 30 ++++++++++--- modules/jsdoc/name.js | 12 +++--- modules/jsdoc/src/handlers.js | 28 ++++++++---- modules/jsdoc/src/parser.js | 47 ++++++++++++++++----- modules/jsdoc/src/scanner.js | 5 ++- modules/jsdoc/tag/dictionary/definitions.js | 16 ++++--- modules/underscore/template.js | 34 +++++++++++++++ test/cases/constructstag.js | 9 ++-- test/cases/constructstag2.js | 4 -- test/cases/innerscope.js | 6 ++- test/cases/lends.js | 16 +++++++ test/cases/lends2.js | 16 +++++++ test/cases/memberoftag2.js | 10 +++++ test/runner.js | 2 + test/t/cases/borrowstag2.js | 3 +- test/t/cases/constructstag.js | 13 ++---- test/t/cases/constructstag2.js | 10 +---- test/t/cases/innerscope.js | 9 +++- test/t/cases/lends.js | 14 ++++++ test/t/cases/memberoftag2.js | 23 ++++++++++ 20 files changed, 235 insertions(+), 72 deletions(-) create mode 100644 modules/underscore/template.js create mode 100644 test/cases/lends.js create mode 100644 test/cases/lends2.js create mode 100644 test/cases/memberoftag2.js create mode 100644 test/t/cases/lends.js create mode 100644 test/t/cases/memberoftag2.js diff --git a/modules/jsdoc/doclet.js b/modules/jsdoc/doclet.js index 94ce356e..43b03fc3 100644 --- a/modules/jsdoc/doclet.js +++ b/modules/jsdoc/doclet.js @@ -79,15 +79,21 @@ @param {string} sid - The longname of the symbol that this doclet is a member of. */ exports.Doclet.prototype.setMemberof = function(sid) { - /** The symbol that contains this one, if any. */ - this.memberof = sid; + /** + The longname of the symbol that contains this one, if any. + @type string + */ + this.memberof = sid.replace(/\.prototype/g, '#'); } /** Set the `longname` property of this doclet. @param {string} name */ exports.Doclet.prototype.setLongname = function(name) { - /** The fully resolved symbol name. */ + /** + The fully resolved symbol name. + @type string + */ this.longname = name; if (jsdoc.tag.dictionary.isNamespace(this.kind)) { this.longname = jsdoc.name.applyNamespace(this.longname, this.kind); @@ -99,11 +105,17 @@ @param {string} target - The name the symbol is being assigned to. */ exports.Doclet.prototype.borrow = function(source, target) { + var about = {from: source}; + if (target) about.as = target; + if (!this.borrowed) { - /** A list of symbols that are borrowed by this one, if any. */ + /** + A list of symbols that are borrowed by this one, if any. + @type Array. + */ this.borrowed = []; } - this.borrowed.push( {from: source, as: (target||source)} ); + this.borrowed.push(about); } /** Add a symbol to this doclet's `augments` array. @@ -111,13 +123,17 @@ */ exports.Doclet.prototype.augment = function(base) { if (!this.augments) { - /** A list of symbols that are augmented by this one, if any. */ + /** + A list of symbols that are augmented by this one, if any. + @type Array. + */ this.augments = []; } this.augments.push(base); } - /** Set the `meta` property of this doclet. + /** + Set the `meta` property of this doclet. @param {object} meta */ exports.Doclet.prototype.setMeta = function(meta) { diff --git a/modules/jsdoc/name.js b/modules/jsdoc/name.js index 9eca76ca..bfd7c352 100644 --- a/modules/jsdoc/name.js +++ b/modules/jsdoc/name.js @@ -24,7 +24,7 @@ parentDoc; name = name? (''+name).replace(/\.prototype\.?/g, '#') : ''; - + // member of a var in an outer scope? if (name && !memberof && doclet.meta.code && doclet.meta.code.funcscope) { name = doclet.longname = doclet.meta.code.funcscope + '~' + name; @@ -34,13 +34,13 @@ memberof = memberof.replace(/\.prototype\.?/g, '#'); // the name is a fullname, like @name foo.bar, @memberof foo - if (name.indexOf(memberof) === 0) { + if (name && name.indexOf(memberof) === 0) { about = exports.shorten(name); } - else if ( /([#.~])$/.test(memberof) ) { // like @memberof foo# or @memberof foo~ + else if (name && /([#.~])$/.test(memberof) ) { // like @memberof foo# or @memberof foo~ about = exports.shorten(memberof + name); } - else if ( doclet.scope ) { // like @memberof foo# or @memberof foo~ + else if (name && doclet.scope ) { // like @memberof foo# or @memberof foo~ about = exports.shorten(memberof + scopeToPunc[doclet.scope] + name); } } @@ -52,8 +52,6 @@ doclet.name = about.name; } - - if (about.memberof) { doclet.setMemberof(about.memberof); } @@ -80,6 +78,8 @@ if (about.variation) { doclet.variation = about.variation; } + +//dump('doclet', doclet); } function quoteUnsafe(name, kind) { // docspaced names may have unsafe characters which need to be quoted by us diff --git a/modules/jsdoc/src/handlers.js b/modules/jsdoc/src/handlers.js index 20cc02de..ec67752e 100644 --- a/modules/jsdoc/src/handlers.js +++ b/modules/jsdoc/src/handlers.js @@ -7,6 +7,7 @@ /** Attach these event handlers to a particular instance of a parser. + @param parser */ exports.attachTo = function(parser) { var jsdoc = {doclet: require('jsdoc/doclet')}; @@ -14,6 +15,7 @@ // handles JSDoc comments that include a @name tag -- the code is ignored in such a case parser.on('jsdocCommentFound', function(e) { var newDoclet = new jsdoc.doclet.Doclet(e.comment, e); + if (!newDoclet.name) { return false; // only interested in virtual comments (with a @name) here } @@ -36,13 +38,13 @@ function newSymbolDoclet(docletSrc, e) { var newDoclet = new jsdoc.doclet.Doclet(docletSrc, e); - + // an undocumented symbol right after a virtual comment? rhino mistakenly connected the two - if (newDoclet.name) { // there was a @name in comment - // try again, without the comment - e.comment = '@undocumented'; - newDoclet = new jsdoc.doclet.Doclet(e.comment, e); - } + if (newDoclet.name) { // there was a @name in comment + // try again, without the comment + e.comment = '@undocumented'; + newDoclet = new jsdoc.doclet.Doclet(e.comment, e); + } if (newDoclet.alias) { newDoclet.addTag('name', newDoclet.alias); @@ -50,7 +52,6 @@ } else if (e.code && e.code.name) { // we need to get the symbol name from code newDoclet.addTag('name', e.code.name); - if (!newDoclet.memberof && e.astnode) { var memberofName, scope; @@ -114,9 +115,20 @@ this.fire('newDoclet', e); if (!e.defaultPrevented) { - this.addResult(newDoclet); + if ( !filter(newDoclet) ) { + this.addResult(newDoclet); + } } } } + + function filter(doclet) { + // you can't document prototypes + if ( /#$/.test(doclet.longname) ) return true; + // you can't document symbols added by the parser with a dummy name + if (doclet.meta.code && doclet.meta.code.name === '____') return true; + + return false; + } } })(); \ No newline at end of file diff --git a/modules/jsdoc/src/parser.js b/modules/jsdoc/src/parser.js index a30f75c7..daa6b722 100644 --- a/modules/jsdoc/src/parser.js +++ b/modules/jsdoc/src/parser.js @@ -12,7 +12,7 @@ /** * @class - * @mixes module:common/events + * @mixes module:common/events.* * * @example * var jsdocParser = new (require('jsdoc/src/parser').Parser)(); @@ -24,6 +24,7 @@ require('common/util').mixin(exports.Parser.prototype, require('common/events')); /** + * Parse the given source files for JSDoc comments. * @param {Array} sourceFiles * @param {string} [encoding=utf8] * @@ -76,7 +77,7 @@ } /** - * @param {Object} The parse result to add to the result buffer. + * @param {Object} o The parse result to add to the result buffer. */ exports.Parser.prototype.addResult = function(o) { this._resultBuffer.push(o); @@ -95,8 +96,7 @@ exports.Parser.prototype._parseSourceCode = function(sourceCode, sourceName) { currentSourceName = sourceName; - // merge adjacent doclets - sourceCode = sourceCode.replace(/\*\/\/\*\*+/g, '@also'); + sourceCode = pretreat(sourceCode); var ast = parserFactory().parse(sourceCode, sourceName, 1); @@ -116,6 +116,14 @@ currentSourceName = ''; } + function pretreat(code) { + return code + // merge adjacent doclets + .replace(/\*\/\/\*\*+/g, '@also') + // make lent objectliterals documentable by giving them a dummy name + .replace(/(\/\*\*[\s\S]*@lends\b[\s\S]*\*\/\s*)\{/g, '$1____ = {'); + } + /** * Given a node, determine what the node is a member of. * @param {astnode} node @@ -204,7 +212,7 @@ doclet = this.refs['astnode'+enclosingFunction.hashCode()]; - if ( doclet && doclet.vars && ~doclet.vars.indexOf(basename) ) { + if ( doclet && doclet.meta.vars && ~doclet.meta.vars.indexOf(basename) ) { return doclet.longname; } @@ -303,8 +311,8 @@ funcDoc = currentParser.refs[func]; if (funcDoc) { - funcDoc.vars = func.vars || []; - funcDoc.vars.push(e.code.name); + funcDoc.meta.vars = funcDoc.meta.vars || []; + funcDoc.meta.vars.push(e.code.name); } } @@ -362,6 +370,7 @@ /** * Attempts to find the name and type of the given node. * @private + * @memberof module:src/parser.Parser */ function aboutNode(node) { about = {}; @@ -408,7 +417,9 @@ return about; } - /** @private */ + /** @private + @memberof module:src/parser.Parser + */ function nodeToString(node) { var str; @@ -442,7 +453,9 @@ return '' + str; }; - /** @private */ + /** @private + @memberof module:src/parser.Parser + */ function getTypeName(node) { var type = ''; @@ -453,9 +466,21 @@ return type; } - /** @private */ + /** @private + @memberof module:src/parser.Parser + */ function isValidJsdoc(commentSrc) { return commentSrc.indexOf('/***') !== 0; /*** ignore comments that start with many stars ***/ } -})(); \ No newline at end of file +})(); + +/** + Fired whenever the parser encounters a JSDoc comment in the current source code. + @event jsdocCommentFound + @memberof module:jsdoc/src/parser.Parser + @param e + @param e.comment The text content of the JSDoc comment + @param e.lineno The line number associated with the found comment. + @param e.filename The file name associated with the found comment. + */ \ No newline at end of file diff --git a/modules/jsdoc/src/scanner.js b/modules/jsdoc/src/scanner.js index df6a92a0..9f2fdb01 100644 --- a/modules/jsdoc/src/scanner.js +++ b/modules/jsdoc/src/scanner.js @@ -15,10 +15,11 @@ /** @constructor + @mixes module:common.events.* */ - var Scanner = exports.Scanner = function() { + exports.Scanner = function() { } - common.mixin(Scanner.prototype, common.events); + common.mixin(exports.Scanner.prototype, common.events); /** Recursively searches the given searchPaths for js files. diff --git a/modules/jsdoc/tag/dictionary/definitions.js b/modules/jsdoc/tag/dictionary/definitions.js index f5e0557d..4e33e3b8 100644 --- a/modules/jsdoc/tag/dictionary/definitions.js +++ b/modules/jsdoc/tag/dictionary/definitions.js @@ -26,7 +26,8 @@ onTagged: function(doclet, tag) { doclet.alias = tag.value; } - }); + }) + .synonym('lends'); dictionary.defineTag('author', { mustHaveValue: true, @@ -93,11 +94,12 @@ }); dictionary.defineTag('constructs', { + mustHaveValue: true, onTagged: function(doclet, tag) { var ownerClassName = firstWordOf(tag.value); - doclet.addTag('alias', ownerClassName + '.constructor'); - doclet.addTag('memberof', ownerClassName); - doclet.addTag('kind', 'function'); + doclet.addTag('alias', ownerClassName/* + '.constructor'*/); + //doclet.addTag('memberof', ownerClassName); + doclet.addTag('kind', 'class'); } }); @@ -188,7 +190,11 @@ .synonym('overview'); dictionary.defineTag('fires', { - mustHaveValue: true + mustHaveValue: true, + onTagged: function(doclet, tag) { + if (!doclet.fires) { doclet.fires = []; } + doclet.fires.push(tag.value); + } }); dictionary.defineTag('function', { diff --git a/modules/underscore/template.js b/modules/underscore/template.js new file mode 100644 index 00000000..4f911b6b --- /dev/null +++ b/modules/underscore/template.js @@ -0,0 +1,34 @@ +// By default, Underscore uses ERB-style template delimiters, change the +// following template settings to use alternative delimiters. +exports.settings = { + evaluate : /<%([\s\S]+?)%>/g, + interpolate : /<%=([\s\S]+?)%>/g +}; + +// JavaScript micro-templating, similar to John Resig's implementation. +// Underscore templating handles arbitrary delimiters, preserves whitespace, +// and correctly escapes quotes within interpolated code. +exports.render = function(templateStr, data) { + var settings = exports.settings, + compiledTemplate, + renderFunction; + + compiledTemplate = 'var __p=[],print=function(){__p.push.apply(__p,arguments);};' + + 'with(data||{}){__p.push(\'' + + templateStr.replace(/\\/g, '\\\\') + .replace(/'/g, "\\'") + .replace(settings.interpolate, function(match, code) { + return "'," + code.replace(/\\'/g, "'") + ",'"; + }) + .replace(settings.evaluate || null, function(match, code) { + return "');" + code.replace(/\\'/g, "'") + .replace(/[\r\n\t]/g, ' ') + "__p.push('"; + }) + .replace(/\r/g, '\\r') + .replace(/\n/g, '\\n') + .replace(/\t/g, '\\t') + + "');}return __p.join('');"; + + renderFunction = new Function('data', compiledTemplate); + return data ? renderFunction(data) : renderFunction; +}; \ No newline at end of file diff --git a/test/cases/constructstag.js b/test/cases/constructstag.js index 3e19a8ae..a31a1cd0 100644 --- a/test/cases/constructstag.js +++ b/test/cases/constructstag.js @@ -1,12 +1,9 @@ -/** - Describe your class here - @class TextBlock - */ Classify('TextBlock', { /** Document your constructor function here. @constructs TextBlock + @classdesc Describe your class here @param {object} opts @throws MissingNode */ @@ -17,6 +14,6 @@ Classify('TextBlock', { Document your method here. @memberof TextBlock# */ - align: function() { - } + align: function() { + } }); \ No newline at end of file diff --git a/test/cases/constructstag2.js b/test/cases/constructstag2.js index f539d16e..604d4bad 100644 --- a/test/cases/constructstag2.js +++ b/test/cases/constructstag2.js @@ -1,7 +1,3 @@ -/** - Describe the class here. - @class Menu - */ Classify('Menu', /** @constructs Menu diff --git a/test/cases/innerscope.js b/test/cases/innerscope.js index 6a623f34..5d2d5f5c 100644 --- a/test/cases/innerscope.js +++ b/test/cases/innerscope.js @@ -1,12 +1,16 @@ /** @constructor */ function Message(to) { - var headers = {}; + var headers = {}, + response; /** document me */ headers.to = to; (function() { + /** document me */ + response.code = '200'; + /** document me */ headers.from = ''; })() diff --git a/test/cases/lends.js b/test/cases/lends.js new file mode 100644 index 00000000..6d86ae6d --- /dev/null +++ b/test/cases/lends.js @@ -0,0 +1,16 @@ +/** @class */ +var Person = makeClass( + /** @lends Person# */ + { + /** Set up initial values. */ + initialize: function(name) { + /** The name of the person. */ + this.name = name; + }, + + /** Speak a message. */ + say: function(message) { + return this.name + " says: " + message; + } + } +); \ No newline at end of file diff --git a/test/cases/lends2.js b/test/cases/lends2.js new file mode 100644 index 00000000..d2dd2207 --- /dev/null +++ b/test/cases/lends2.js @@ -0,0 +1,16 @@ + +var Person = makeClass( + /** @lends Person# */ + { + /** @constructs Person */ + initialize: function(name) { + /** The name of the person. */ + this.name = name; + }, + + /** Speak a message. */ + say: function(message) { + return this.name + " says: " + message; + } + } +); \ No newline at end of file diff --git a/test/cases/memberoftag2.js b/test/cases/memberoftag2.js new file mode 100644 index 00000000..b926dc6a --- /dev/null +++ b/test/cases/memberoftag2.js @@ -0,0 +1,10 @@ +create( + 'Observable', + { + /** @memberof Observable */ + cache: [], + + /** @memberof Observable.prototype */ + publish: function(msg) {} + } +); \ No newline at end of file diff --git a/test/runner.js b/test/runner.js index d17dfead..3a608af9 100644 --- a/test/runner.js +++ b/test/runner.js @@ -113,7 +113,9 @@ testFile('test/t/cases/exportstag3.js'); testFile('test/t/cases/exceptiontag.js'); testFile('test/t/cases/globaltag.js'); testFile('test/t/cases/ignoretag.js'); +testFile('test/t/cases/lends.js'); testFile('test/t/cases/memberoftag.js'); +testFile('test/t/cases/memberoftag2.js'); testFile('test/t/cases/moduletag.js'); testFile('test/t/cases/paramtag.js'); testFile('test/t/cases/privatetag.js'); diff --git a/test/t/cases/borrowstag2.js b/test/t/cases/borrowstag2.js index e7fcd17d..151d5f0a 100644 --- a/test/t/cases/borrowstag2.js +++ b/test/t/cases/borrowstag2.js @@ -4,11 +4,10 @@ return ! $.undocumented; })[0]; - //dump(found); + //dump(str); exit(); test('When a symbol has a @borrows tag, that is added to the symbol\'s "borrowed" property and the from is the same as the as property.', function() { assert.equal(str.borrowed.length, 1); assert.equal(str.borrowed[0].from, 'rtrim'); - assert.equal(str.borrowed[0].as, str.borrowed[0].from); }); })(); \ No newline at end of file diff --git a/test/t/cases/constructstag.js b/test/t/cases/constructstag.js index 98baad9b..ec8c9d61 100644 --- a/test/t/cases/constructstag.js +++ b/test/t/cases/constructstag.js @@ -1,18 +1,11 @@ (function() { var docSet = testhelpers.getDocSetFromFile('test/cases/constructstag.js'), - textblock = docSet.getByLongname('TextBlock')[0], - textblockConstructor = docSet.getByLongname('TextBlock.constructor')[0]; + textblock = docSet.getByLongname('TextBlock')[0]; //dump(docSet.doclets); exit(0); - test('When a symbol has an @class tag, it is documented as a class.', function() { - assert.equal(textblock.name, 'TextBlock'); + test('When a symbol has an @constructs tag, it is documented as a class with that name.', function() { assert.equal(textblock.kind, 'class'); - }); - - test('When a symbol has an @constructs tag, the doclet has the longname of ".constructor".', function() { - assert.equal(textblockConstructor.name, 'constructor'); - assert.equal(textblockConstructor.memberof, 'TextBlock'); - assert.equal(textblockConstructor.kind, 'function'); + assert.equal(textblock.longname, 'TextBlock'); }); })(); \ No newline at end of file diff --git a/test/t/cases/constructstag2.js b/test/t/cases/constructstag2.js index ca338542..2cd8e5fc 100644 --- a/test/t/cases/constructstag2.js +++ b/test/t/cases/constructstag2.js @@ -1,18 +1,12 @@ (function() { var docSet = testhelpers.getDocSetFromFile('test/cases/constructstag2.js'), - menu = docSet.getByLongname('Menu')[0], - menuConstructor = docSet.getByLongname('Menu.constructor')[0]; + menu = docSet.getByLongname('Menu')[0]; //dump(docSet.doclets); exit(0); - test('When a symbol has an @class tag, it is documented as a class.', function() { + test('When a symbol has an @constructs tag, it is documented as a class.', function() { assert.equal(menu.name, 'Menu'); assert.equal(menu.kind, 'class'); }); - test('When an anonymous function symbol has an @constructs tag, the doclet has the longname of ".constructor".', function() { - assert.equal(menuConstructor.name, 'constructor'); - assert.equal(menuConstructor.memberof, 'Menu'); - assert.equal(menuConstructor.kind, 'function'); - }); })(); \ No newline at end of file diff --git a/test/t/cases/innerscope.js b/test/t/cases/innerscope.js index df8ef3ce..8e6bee7d 100644 --- a/test/t/cases/innerscope.js +++ b/test/t/cases/innerscope.js @@ -1,14 +1,19 @@ (function() { var docSet = testhelpers.getDocSetFromFile('test/cases/innerscope.js'), to = docSet.getByLongname('Message~headers.to'), - from = docSet.getByLongname('Message~headers.from'); + from = docSet.getByLongname('Message~headers.from'), + response = docSet.getByLongname('Message~response.code'); - //dump(docSet); + //dump(docSet); exit(); test('When a member of a var member is documented.', function() { assert.equal(to.length, 1, 'It is like Outer~inner.member.'); }); + test('When a second member of a var member is documented.', function() { + assert.equal(response.length, 1, 'It is like Outer~inner.member.'); + }); + test('When a deeply nested member of a var member is documented.', function() { assert.equal(from.length, 1, 'It is still like Outer~inner.member.'); }); diff --git a/test/t/cases/lends.js b/test/t/cases/lends.js new file mode 100644 index 00000000..e745d432 --- /dev/null +++ b/test/t/cases/lends.js @@ -0,0 +1,14 @@ +(function() { + var docSet = testhelpers.getDocSetFromFile('test/cases/lends.js'), + init = docSet.getByLongname('Person#initialize'), + say = docSet.getByLongname('Person#say'), + name = docSet.getByLongname('Person#say'); + + //dump(docSet); + + test('When a documented member is inside an objlit associated with a @lends tag.', function() { + assert.equal(init.length, 1, 'The member should be documented as a member of the lendee.'); + assert.equal(name.length, 1, 'The this member should be documented as a member of the lendee.'); + }); + +})(); \ No newline at end of file diff --git a/test/t/cases/memberoftag2.js b/test/t/cases/memberoftag2.js new file mode 100644 index 00000000..dc40e577 --- /dev/null +++ b/test/t/cases/memberoftag2.js @@ -0,0 +1,23 @@ +(function() { + var docSet = testhelpers.getDocSetFromFile('test/cases/memberoftag2.js'), + publish = docSet.getByLongname('Observable#publish')[0], + cache = docSet.getByLongname('Observable.cache')[0]; + + //dump(docSet.doclets); exit(0); + + test('A symbol is documented as a static @memberof a class.', function() { + assert.equal(typeof cache, 'object', 'it should appear as a static member of that class.'); + assert.equal(cache.memberof, 'Observable'); + assert.equal(cache.scope, 'static'); + assert.equal(cache.name, 'cache'); + assert.equal(cache.longname, 'Observable.cache'); + }); + + test('A symbol is documented as a static @memberof a class prototype.', function() { + assert.equal(typeof publish, 'object', 'it should appear as an instance member of that class.'); + assert.equal(publish.memberof, 'Observable'); + assert.equal(publish.scope, 'instance'); + assert.equal(publish.name, 'publish'); + assert.equal(publish.longname, 'Observable#publish'); + }); +})(); \ No newline at end of file From 6a52c03201c0ce2ed7654b3ffa1db2d2a137c180 Mon Sep 17 00:00:00 2001 From: Michael Mathews Date: Thu, 24 Feb 2011 17:09:10 +0000 Subject: [PATCH 9/9] Work on templates. Replaced mustache with Underscore Template code. --- LICENSE.md | 34 +- modules/janl/mustache.js | 348 ------------------ modules/jsdoc/name.js | 2 +- modules/jsdoc/src/parser.js | 15 +- modules/jsdoc/tag/dictionary.js | 20 +- modules/jsdoc/tag/dictionary/definitions.js | 11 +- package.json | 2 +- templates/default/publish.js | 312 ++++++++-------- .../default/static/styles/jsdoc-default.css | 330 +++++++---------- templates/default/static/styles/node-dark.css | 152 +++++++- templates/default/tmpl/classes.mustache | 10 - templates/default/tmpl/container.mustache | 82 ----- templates/default/tmpl/container.tmpl | 176 +++++++++ templates/default/tmpl/example.mustache | 12 - templates/default/tmpl/example.tmpl | 2 + templates/default/tmpl/examples.tmpl | 10 + templates/default/tmpl/exceptions.mustache | 28 -- templates/default/tmpl/exceptions.tmpl | 28 ++ templates/default/tmpl/fires.tmpl | 3 + templates/default/tmpl/index.mustache | 189 ---------- templates/default/tmpl/method.tmpl | 65 ++++ templates/default/tmpl/methods.mustache | 33 -- templates/default/tmpl/namespaces.mustache | 10 - templates/default/tmpl/params.mustache | 53 --- templates/default/tmpl/params.tmpl | 115 ++++++ templates/default/tmpl/properties.mustache | 88 ----- templates/default/tmpl/properties.tmpl | 47 +++ templates/default/tmpl/returns.mustache | 28 -- templates/default/tmpl/returns.tmpl | 31 ++ 29 files changed, 943 insertions(+), 1293 deletions(-) delete mode 100644 modules/janl/mustache.js delete mode 100644 templates/default/tmpl/classes.mustache delete mode 100644 templates/default/tmpl/container.mustache create mode 100644 templates/default/tmpl/container.tmpl delete mode 100644 templates/default/tmpl/example.mustache create mode 100644 templates/default/tmpl/example.tmpl create mode 100644 templates/default/tmpl/examples.tmpl delete mode 100644 templates/default/tmpl/exceptions.mustache create mode 100644 templates/default/tmpl/exceptions.tmpl create mode 100644 templates/default/tmpl/fires.tmpl delete mode 100644 templates/default/tmpl/index.mustache create mode 100644 templates/default/tmpl/method.tmpl delete mode 100644 templates/default/tmpl/methods.mustache delete mode 100644 templates/default/tmpl/namespaces.mustache delete mode 100644 templates/default/tmpl/params.mustache create mode 100644 templates/default/tmpl/params.tmpl delete mode 100644 templates/default/tmpl/properties.mustache create mode 100644 templates/default/tmpl/properties.tmpl delete mode 100644 templates/default/tmpl/returns.mustache create mode 100644 templates/default/tmpl/returns.tmpl diff --git a/LICENSE.md b/LICENSE.md index 4437cd5c..ba2d2fb9 100644 --- a/LICENSE.md +++ b/LICENSE.md @@ -7,7 +7,7 @@ compliance with the License. You have permission to use it for commercial, non-commercial, or any other purpose you like, according to the License below. -Copyright (c) 2010, 2011 Michael Mathews +Copyright (c) 2011 Michael Mathews All rights reserved. You may obtain a copy of the License at @@ -158,33 +158,19 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. You may obtain the source code for sqlitejdbc at https://github.com/crawshaw/sqlitejdbc -MustacheJS (templates/lib/janl/mustache.js) +Underscore Template (templates/lib/underscore/template.js) ---- -Copyright (c) 2009 Chris Wanstrath (Ruby) -Copyright (c) 2010 Jan Lehnardt (JavaScript) +Underscore.js 1.1.4 -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +Copyright (c) 2011 Jeremy Ashkenas, DocumentCloud Inc. -You may obtain the source code for MustacheJS at -https://github.com/janl/mustache.js +Underscore is freely distributable under the MIT license. +Portions of Underscore are inspired or borrowed from Prototype, +Oliver Steele's Functional, and John Resig's Micro-Templating. + +For all details and documentation: +http://documentcloud.github.com/underscore/#template TaffyDB (modules/typicaljoe/taffy.js) ---- diff --git a/modules/janl/mustache.js b/modules/janl/mustache.js deleted file mode 100644 index caae3181..00000000 --- a/modules/janl/mustache.js +++ /dev/null @@ -1,348 +0,0 @@ -/* - * CommonJS-compatible mustache.js module - * - * See http://github.com/janl/mustache.js for more info. - */ - -/* - mustache.js — Logic-less templates in JavaScript - - See http://mustache.github.com/ for more info. -*/ - -var Mustache = function() { - var Renderer = function() {}; - - Renderer.prototype = { - otag: "{{", - ctag: "}}", - pragmas: {}, - buffer: [], - pragmas_implemented: { - "IMPLICIT-ITERATOR": true, - "ARRAY-ORDINALS": true // define #first? and #last? when looping arrays - }, - context: {}, - - render: function(template, context, partials, in_recursion) { - // reset buffer & set context - if(!in_recursion) { - this.context = context; - this.buffer = []; // TODO: make this non-lazy - } - - // fail fast - if(!this.includes("", template)) { - if(in_recursion) { - return template; - } else { - this.send(template); - return; - } - } - - template = this.render_pragmas(template); - var html = this.render_section(template, context, partials); - if(in_recursion) { - return this.render_tags(html, context, partials, in_recursion); - } - - this.render_tags(html, context, partials, in_recursion); - }, - - /* - Sends parsed lines - */ - send: function(line) { - if(line != "") { - this.buffer.push(line); - } - }, - - /* - Looks for %PRAGMAS - */ - render_pragmas: function(template) { - // no pragmas - if(!this.includes("%", template)) { - return template; - } - - var that = this; - var regex = new RegExp(this.otag + "%([\\w-]+) ?([\\w]+=[\\w]+)?" + - this.ctag); - return template.replace(regex, function(match, pragma, options) { - if(!that.pragmas_implemented[pragma]) { - throw({message: - "This implementation of mustache doesn't understand the '" + - pragma + "' pragma"}); - } - that.pragmas[pragma] = {}; - if(options) { - var opts = options.split("="); - that.pragmas[pragma][opts[0]] = opts[1]; - } - return ""; - // ignore unknown pragmas silently - }); - }, - - /* - Tries to find a partial in the curent scope and render it - */ - render_partial: function(name, context, partials) { - name = this.trim(name); - if(!partials || partials[name] === undefined) { - throw({message: "unknown_partial '" + name + "'"}); - } - if(typeof(context[name]) != "object") { - return this.render(partials[name], context, partials, true); - } - return this.render(partials[name], context[name], partials, true); - }, - - /* - Renders inverted (^) and normal (#) sections - */ - render_section: function(template, context, partials) { - if(!this.includes("#", template) && !this.includes("^", template)) { - return template; - } - - var that = this; - // CSW - Added "+?" so it finds the tighest bound, not the widest - var regex = new RegExp(this.otag + "(\\^|\\#)\\s*(.+)\\s*" + this.ctag + - "\n*([\\s\\S]+?)" + this.otag + "\\/\\s*\\2\\s*" + this.ctag + - "\\s*", "mg"); - - // for each {{#foo}}{{/foo}} section do... - return template.replace(regex, function(match, type, name, content) { - var value = that.find(name, context); - if(type == "^") { // inverted section - if(!value || that.is_array(value) && value.length === 0) { - // false or empty list, render it - return that.render(content, context, partials, true); - } else { - return ""; - } - } else if(type == "#") { // normal section - if(that.is_array(value)) { // Enumerable, Let's loop! - var len = value.length; - return value.map(function(row, i) { - return that.render(content, that.create_context(row, {first: i === 0, last: i === len-1}), - partials, true); - }).join(""); - } else if(that.is_object(value)) { // Object, Use it as subcontext! - return that.render(content, that.create_context(value), - partials, true); - } else if(typeof value === "function") { - // higher order section - return value.call(context, content, function(text) { - return that.render(text, context, partials, true); - }); - } else if(value) { // boolean section - return that.render(content, context, partials, true); - } else { - return ""; - } - } - }); - }, - - /* - Replace {{foo}} and friends with values from our view - */ - render_tags: function(template, context, partials, in_recursion) { - // tit for tat - var that = this; - - var new_regex = function() { - return new RegExp(that.otag + "(=|!|>|\\{|%)?([^\\/#\\^]+?)\\1?" + - that.ctag + "+", "g"); - }; - - var regex = new_regex(); - var tag_replace_callback = function(match, operator, name) { - switch(operator) { - case "!": // ignore comments - return ""; - case "=": // set new delimiters, rebuild the replace regexp - that.set_delimiters(name); - regex = new_regex(); - return ""; - case ">": // render partial - return that.render_partial(name, context, partials); - case "{": // the triple mustache is unescaped - return that.find(name, context); - default: // escape the value - return that.escape(that.find(name, context)); - } - }; - var lines = template.split("\n"); - for(var i = 0; i < lines.length; i++) { - lines[i] = lines[i].replace(regex, tag_replace_callback, this); - if(!in_recursion) { - this.send(lines[i]); - } - } - - if(in_recursion) { - return lines.join("\n"); - } - }, - - set_delimiters: function(delimiters) { - var dels = delimiters.split(" "); - this.otag = this.escape_regex(dels[0]); - this.ctag = this.escape_regex(dels[1]); - }, - - escape_regex: function(text) { - // thank you Simon Willison - if(!arguments.callee.sRE) { - var specials = [ - '/', '.', '*', '+', '?', '|', - '(', ')', '[', ']', '{', '}', '\\' - ]; - arguments.callee.sRE = new RegExp( - '(\\' + specials.join('|\\') + ')', 'g' - ); - } - return text.replace(arguments.callee.sRE, '\\$1'); - }, - - /* - find `name` in current `context`. That is find me a value - from the view object - */ - find: function(name, context) { - name = this.trim(name); - - // Checks whether a value is thruthy or false or 0 - function is_kinda_truthy(bool) { - return bool === false || bool === 0 || bool; - } - - var value; - if(is_kinda_truthy(context[name])) { - value = context[name]; - } else if(is_kinda_truthy(this.context[name])) { - value = this.context[name]; - } - - if(typeof value === "function") { - return value.apply(context); - } - if(value !== undefined) { - return value; - } - // silently ignore unkown variables - return ""; - }, - - // Utility methods - - /* includes tag */ - includes: function(needle, haystack) { - return haystack.indexOf(this.otag + needle) != -1; - }, - - /* - Does away with nasty characters - */ - escape: function(s) { - s = String(s === null ? "" : s); - return s.replace(/&(?!\w+;)|["'<>\\]/g, function(s) { - switch(s) { - case "&": return "&"; - case "\\": return "\\\\"; - case '"': return '"'; - case "'": return '''; - case "<": return "<"; - case ">": return ">"; - default: return s; - } - }); - }, - - // by @langalex, support for arrays of strings - create_context: function(_context, opts) { - if(this.is_object(_context)) { - if (this.pragmas["ARRAY-ORDINALS"] && opts) { - _context['first?'] = opts.first || false; - _context['last?'] = opts.last || false; - } - return _context; - } else { - var iterator = "."; - if(this.pragmas["IMPLICIT-ITERATOR"]) { - iterator = this.pragmas["IMPLICIT-ITERATOR"].iterator; - } - var ctx = {}; - ctx[iterator] = _context; - if (this.pragmas["ARRAY-ORDINALS"] && opts){ - ctx['first?'] = opts.first || false; - ctx['last?'] = opts.last || false; - } - return ctx; - } - }, - - is_object: function(a) { - return a && typeof a == "object"; - }, - - is_array: function(a) { - return Object.prototype.toString.call(a) === '[object Array]'; - }, - - /* - Gets rid of leading and trailing whitespace - */ - trim: function(s) { - return s.replace(/^\s*|\s*$/g, ""); - }, - - /* - Why, why, why? Because IE. Cry, cry cry. - */ - map: function(array, fn) { - if (typeof array.map == "function") { - return array.map(fn); - } else { - var r = []; - var l = array.length; - for(var i = 0; i < l; i++) { - r.push(fn(array[i])); - } - return r; - } - } - }; - - return({ - name: "mustache.js", - version: "0.3.1-dev", - - /* - Turns a template and view into HTML - */ - to_html: function(template, view, partials, send_fun) { - var renderer = new Renderer(); - if(send_fun) { - renderer.send = send_fun; - } - renderer.render(template, view, partials); - if(!send_fun) { - return renderer.buffer.join("\n"); - } - } - }); -}(); - -exports.name = Mustache.name; -exports.version = Mustache.version; - -exports.to_html = function() { - return Mustache.to_html.apply(this, arguments); -}; diff --git a/modules/jsdoc/name.js b/modules/jsdoc/name.js index bfd7c352..b247dbcb 100644 --- a/modules/jsdoc/name.js +++ b/modules/jsdoc/name.js @@ -142,7 +142,7 @@ longname = longname.replace( /\.prototype\.?/g, '#' ); var parts = longname? - longname.match( /^(:?(.+)([#.~]))?(.+?)$/ ).reverse() + (longname.match( /^(:?(.+)([#.~]))?(.+?)$/ ) || []).reverse() : ['']; var name = parts[0], diff --git a/modules/jsdoc/src/parser.js b/modules/jsdoc/src/parser.js index daa6b722..070c6fe2 100644 --- a/modules/jsdoc/src/parser.js +++ b/modules/jsdoc/src/parser.js @@ -14,7 +14,7 @@ * @class * @mixes module:common/events.* * - * @example + * @example Create a new parser. * var jsdocParser = new (require('jsdoc/src/parser').Parser)(); */ exports.Parser = function() { @@ -25,7 +25,7 @@ /** * Parse the given source files for JSDoc comments. - * @param {Array} sourceFiles + * @param {Array.} sourceFiles An array of filepaths to the JavaScript sources. * @param {string} [encoding=utf8] * * @fires jsdocCommentFound @@ -34,7 +34,7 @@ * @fires fileBegin * @fires fileComplete * - * @example + * @example Parse two source files. * var myFiles = ['file1.js', 'file2.js']; * var docs = jsdocParser.parse(myFiles); */ @@ -127,6 +127,7 @@ /** * Given a node, determine what the node is a member of. * @param {astnode} node + * @returns {string} The long name of the node that this is a member of. */ exports.Parser.prototype.astnodeToMemberof = function(node) { var memberof = {}; @@ -479,8 +480,8 @@ Fired whenever the parser encounters a JSDoc comment in the current source code. @event jsdocCommentFound @memberof module:jsdoc/src/parser.Parser - @param e - @param e.comment The text content of the JSDoc comment - @param e.lineno The line number associated with the found comment. - @param e.filename The file name associated with the found comment. + @param {event} e + @param {string} e.comment The text content of the JSDoc comment + @param {number} e.lineno The line number associated with the found comment. + @param {string} e.filename The file name associated with the found comment. */ \ No newline at end of file diff --git a/modules/jsdoc/tag/dictionary.js b/modules/jsdoc/tag/dictionary.js index a99630a8..b0484168 100644 --- a/modules/jsdoc/tag/dictionary.js +++ b/modules/jsdoc/tag/dictionary.js @@ -1,17 +1,14 @@ /** - @module jsdoc/tag/dictionary - + @overview @author Michael Mathews @license Apache License 2.0 - See file 'LICENSE.md' in this project. */ (function() { var _synonyms = {}, _definitions = {}, - _namespaces = [], - dictionary; + _namespaces = []; - /** @constructor */ - function TagDefinition(title, etc) { + function _TagDefinition(title, etc) { etc = etc || {}; this.title = dictionary.normalise(title); @@ -23,14 +20,16 @@ } } - TagDefinition.prototype.synonym = function(synonymName) { + _TagDefinition.prototype.synonym = function(synonymName) { _synonyms[synonymName.toLowerCase()] = this.title; return this; // chainable } - dictionary = { + /** @exports jsdoc/tag/dictionary */ + var dictionary = { + /** @function */ defineTag: function(title, opts) { - _definitions[title] = new TagDefinition(title, opts); + _definitions[title] = new _TagDefinition(title, opts); if (opts.isNamespace) { _namespaces.push(title); @@ -39,6 +38,7 @@ return _definitions[title]; }, + /** @function */ lookUp: function(title) { title = dictionary.normalise(title); @@ -49,10 +49,12 @@ return false; }, + /** @function */ isNamespace: function(kind) { return ( ~ _namespaces.indexOf(kind) ); }, + /** @function */ normalise: function(title) { canonicalName = title.toLowerCase(); diff --git a/modules/jsdoc/tag/dictionary/definitions.js b/modules/jsdoc/tag/dictionary/definitions.js index 4e33e3b8..6214f73e 100644 --- a/modules/jsdoc/tag/dictionary/definitions.js +++ b/modules/jsdoc/tag/dictionary/definitions.js @@ -58,15 +58,17 @@ dictionary.defineTag('class', { onTagged: function(doclet, tag) { + doclet.addTag('kind', 'class'); + // handle special case where both @class and @constructor tags exist in same doclet if (tag.originalTitle === 'class') { - if ( /@construct(s|or)\b/i.test(doclet.comment) ) { + var looksLikeDesc = (tag.value || '').match(/\S+\s+\S+/); // multiple words after @class? + if ( looksLikeDesc || /@construct(s|or)\b/i.test(doclet.comment) ) { doclet.classdesc = tag.value; // treat the @class tag as a @classdesc tag instead return; } } - doclet.addTag('kind', 'class'); setDocletNameToValue(doclet, tag); } }) @@ -97,8 +99,7 @@ mustHaveValue: true, onTagged: function(doclet, tag) { var ownerClassName = firstWordOf(tag.value); - doclet.addTag('alias', ownerClassName/* + '.constructor'*/); - //doclet.addTag('memberof', ownerClassName); + doclet.addTag('alias', ownerClassName); doclet.addTag('kind', 'class'); } }); @@ -172,7 +173,7 @@ doclet.addTag('alias', modName); doclet.addTag('kind', 'module'); - doclet.addTag('undocumented'); + //doclet.addTag('undocumented'); } }) .synonym('defines'); diff --git a/package.json b/package.json index ae59bd47..282285c8 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "jsdoc", "version": "3.0.0beta1", - "revision": "2011-02-11-2113", + "revision": "2011-02-24-1703", "description": "An automatic documentation generator for javascript.", "keywords": [ "documentation", "javascript" ], "licenses": [ diff --git a/templates/default/publish.js b/templates/default/publish.js index cc322ce7..c82edd2b 100644 --- a/templates/default/publish.js +++ b/templates/default/publish.js @@ -1,7 +1,10 @@ (function() { - var Mustache = require('janl/mustache'), + var template = require('underscore/template'), fs = require('fs'); + + template.settings.evaluate = /<\?js([\s\S]+?)\?>/g; + template.settings.interpolate = /<\?js=([\s\S]+?)\?>/g; /** @global @@ -9,27 +12,49 @@ @param {object} opts */ publish = function(data, opts) { - var out = ''; + var out = '', + containerTemplate = template.render(fs.read(BASEDIR + 'templates/default/tmpl/container.tmpl')); - var helpers = { - linkTo: function() { - return function(text, render) { - var linkTo, - text = render(text); - - if ( !data.find({longname: text}).length ) { return text; } - - linkTo = text.replace(/#/g, '%23'); - return '' + text + ''; - } + function render(tmpl, partialData) { + var renderFunction = arguments.callee.cache[tmpl]; + if (!renderFunction) { + renderFunction = arguments.callee.cache[tmpl] = template.render(fs.read(BASEDIR + 'templates/default/tmpl/'+tmpl)); } - }; + partialData.render = arguments.callee; + partialData.find = find; + partialData.htmlsafe = htmlsafe; + + return renderFunction.call(partialData, partialData); + } + render.cache = {}; + + function find(spec) { + return data.get( data.find(spec) ); + } + + function htmlsafe(str) { + return str.replace(/' + text + ''; +// } +// } +// }; function summarize(doclet) { var desc = doclet.description || ''; desc = desc.replace(/<\/?p>/gi, ''); // full text may be HTML, remove P wrapper - desc = trim(desc); + desc = desc.trim(); var m; @@ -37,132 +62,108 @@ doclet.summary = m[1]; doclet.description = m[2]? m[2] : ''; } + + doclet.signature = ''; + doclet.attribs = ''; } - function trim(text) { - return text.replace(/^\s+|\s+$/g, ''); - } - - data.remove({undocumented: true}); - - var packageInfo = (data.get( data.find({kind: 'package'}) ) || []) [0]; - - // add template helpers - data.forEach(function(doclet) { - doclet.hasParams = doclet.params && doclet.params.length > 0; - doclet.hasReturns = doclet.returns && doclet.returns.length > 0; - doclet.hasBorrowed = doclet.borrowed && doclet.borrowed.length > 0; - doclet.hasExceptions = doclet.exceptions && doclet.exceptions.length > 0; - doclet.hasExamples = doclet.examples && doclet.examples.length > 0; - - summarize(doclet); - }); - - data.orderBy(['longname', 'kind']); - - var containerTemplate = fs.read(BASEDIR + 'templates/default/tmpl/container.mustache'); - var partials = { - paramsTemplate: fs.read(BASEDIR + 'templates/default/tmpl/params.mustache'), - returnsTemplate: fs.read(BASEDIR + 'templates/default/tmpl/returns.mustache'), - methodsTemplate: fs.read(BASEDIR + 'templates/default/tmpl/methods.mustache'), - propertiesTemplate: fs.read(BASEDIR + 'templates/default/tmpl/properties.mustache'), - examplesTemplate: fs.read(BASEDIR + 'templates/default/tmpl/example.mustache'), - namespacesTemplate: fs.read(BASEDIR + 'templates/default/tmpl/namespaces.mustache'), - - classesTemplate: fs.read(BASEDIR + 'templates/default/tmpl/classes.mustache'), - exceptionsTemplate: fs.read(BASEDIR + 'templates/default/tmpl/exceptions.mustache') - }; - - var topLevels = { - projects: [], - globals: [], - modules: [], - namespaces: [], - classes: [], - mixins: [] - }; - - topLevels.globals = data.get( data.find({memberof: {isUndefined: true}}) ); - - var modules = data.get( data.find({kind: 'module'}) ), - classes = data.get( data.find({kind: 'class'}) ), - namespaces = data.get( data.find({kind: 'namespace'}) ); - - modules.forEach(function(m) { - m.methods = data.get( data.find({kind: 'function', memberof: m.longname}) ); - m.hasMethods = (m.methods && m.methods.length > 0); - m.methods.forEach(prepareFunc); - - m.properties = data.get( data.find({kind: 'property', memberof: m.longname}) ); - m.hasProperties = (m.properties && m.properties.length > 0); - m.properties.forEach(prepareProp); - - m.namespaces = data.get( data.find({kind: 'namespace', memberof: m.longname}) ); - m.hasNamespaces = (m.namespaces && m.namespaces.length > 0); - m.namespaces.forEach(prepareNs); - - m.classes = data.get( data.find({kind: 'class', memberof: m.longname}) ); - m.hasClasses = (m.classes && m.classes.length > 0); - - // TODO: namespaces - }); - - classes.forEach(function(c) { - c.methods = data.get( data.find({kind: 'function', memberof: c.longname}) ); - c.hasMethods = (c.methods && c.methods.length > 0); - prepareFunc(c); - c.hasConstructor = true; - c.methods.forEach(prepareFunc); - - c.properties = data.get( data.find({kind: 'property', memberof: c.longname}) ); - c.hasProperties = (c.properties && c.properties.length > 0); - c.properties.forEach(prepareProp); - - c.namespaces = data.get( data.find({kind: 'namespace', memberof: c.longname}) ); - c.hasNamespaces = (c.namespaces && c.namespaces.length > 0); - c.namespaces.forEach(prepareNs); - - c.classes = data.get( data.find({kind: 'class', memberof: c.longname}) ); - c.hasClasses = (c.classes && c.classes.length > 0); - }); - - namespaces.forEach(function(n) { - - n.methods = data.get( data.find({kind: 'function', memberof: n.longname}) ); - n.hasMethods = (n.methods && n.methods.length > 0); - //prepareNs(n); - n.methods.forEach(prepareFunc); - - n.properties = data.get( data.find({kind: 'property', memberof: n.longname}) ); - n.hasProperties = (n.properties && n.properties.length > 0); - n.properties.forEach(prepareProp); - - n.namespaces = data.get( data.find({kind: 'namespace', memberof: n.longname}) ); - n.hasNamespaces = (n.namespaces && n.namespaces.length > 0); - n.namespaces.forEach(prepareNs); - - n.classes = data.get( data.find({kind: 'class', memberof: n.longname}) ); - n.hasClasses = (n.classes && n.classes.length > 0); - }); - - function prepareFunc(f) { + function addSignatureParams(f) { var pnames = []; if (f.params) { f.params.forEach(function(p) { - if (p.name && p.name.indexOf('.') === -1) { pnames.push(p.name); } + if (p.name && p.name.indexOf('.') === -1) { + if (p.optional) { pnames.push('['+p.name+']'); } + else { pnames.push(p.name); } + } }); } - f.synopsis = (f.kind === 'class'? 'new ' : '') + f.name+'('+pnames.join(', ')+')' - f.hasParams = (f.params && f.params.length > 0); - f.hasReturns = (f.returns && f.returns.length > 0); + + f.signature = (f.signature || '') + '('+pnames.join(', ')+')'; } - function prepareProp(p) { + function addSignatureReturns(f) { + var returnTypes = []; + + if (f.returns) { + f.returns.forEach(function(r) { + if (r.type && r.type.names) { + returnTypes = r.type.names; + } + }); + } + + f.signature = (f.signature || '') + ''+htmlsafe(returnTypes.length? ' ⇒ '+returnTypes.join('|') : '')+''; } - function prepareNs(p) { + function addSignatureType(f) { + var types = []; + + if (f.type && f.type.names) { + types = f.type.names; + } + + f.signature = (f.signature || '') + ''+htmlsafe(types.length? ' :'+types.join('|') : '')+''; } + function addAttribs(f) { + var attribs = []; + + if (f.access && f.access !== 'public') { + attribs.push(f.access); + } + + if (f.scope && f.scope !== 'instance') { + if (f.kind == 'function' || f.kind == 'property') attribs.push(f.scope); + } + + if (f.readonly === true) { + if (f.kind == 'property') attribs.push('readonly'); + } + + f.attribs = ''+htmlsafe(attribs.length? '<'+attribs.join(', ')+'> ' : '')+''; + } + + data.remove({undocumented: true}); + + var packageInfo = (data.get( data.find({kind: 'package'}) ) || []) [0]; + + data.forEach(function(doclet) { + summarize(doclet); + if (doclet.kind === 'function' || doclet.kind === 'class') { + addSignatureParams(doclet); + addSignatureReturns(doclet); + addAttribs(doclet); + } + + if (doclet.kind === 'property') { + addSignatureType(doclet); + addAttribs(doclet) + } + + if (doclet.examples) { + doclet.examples = doclet.examples.map(function(example) { + var caption, code; + + if (example.match(/^\s*([\s\S]+?)<\/caption>(\s*[\n\r])([\s\S]+)$/i)) { + caption = RegExp.$1; + code = RegExp.$3; + } + + return { + caption: caption || '', + code: code || example + }; + }); + } + }); + + data.orderBy(['longname', 'kind', 'version', 'since']); + + // kinds of containers + var globals = data.get( data.find({kind: ['property', 'function'], memberof: {isUndefined: true}}) ), + modules = data.get( data.find({kind: 'module'}) ), + namespaces = data.get( data.find({kind: 'namespace'}) ); + var outdir = opts.destination; if (packageInfo) { outdir += '/' + packageInfo.name + '/' + packageInfo.version + '/'; @@ -172,36 +173,53 @@ // copy static files to outdir var fromDir = BASEDIR + 'templates/default/static', staticFiles = fs.ls(fromDir, 3); + staticFiles.forEach(function(fileName) { var toDir = fs.toDir(fileName.replace(fromDir, outdir)); fs.mkPath(toDir); fs.copyFile(fileName, toDir); }); - - // containers - generate('Modules', modules, 'modules.html'); - generate('Classes', classes, 'classes.html'); - generate('Namespaces', namespaces, 'namespaces.html'); -//dump(classes) + //generate('Globals', globals, 'globals.html'); + //generate('Modules', modules, 'modules.html'); + //generate('Classes', classes, 'classes.html'); + //generate('Namespaces', namespaces, 'namespaces.html'); + + var urlToLongname = {}, + longnameToUrl = {}; + + var classes = data.get(data.find({kind: 'class'})); + for (var i = 0, len = classes.length; i < len; i++) { + var longname = classes[i].longname, + urlSafe = longname.replace(/[^$a-z0-9._-]/gi, '_'); + + // bidirectional lookups: url <=> longname + urlToLongname[urlSafe] = longname; + longnameToUrl[longname] = urlSafe; + } + + for (var longname in longnameToUrl) { + var classes = data.get( data.find({kind: 'class', longname: longname}) ); + generate(classes[0].kind+': '+classes[0].name, classes, longnameToUrl[longname]+'.html'); + } + function generate(title, docs, filename) { + var data = { + title: title, + docs: docs, + + // helpers + render: render, + find: find, + htmlsafe: htmlsafe + }; + var path = outdir + '/' + filename, - html = Mustache.to_html( - containerTemplate, - { - title: title, - docs: docs, - linkTo: helpers.linkTo - }, - partials - ); + html = containerTemplate.call(data, data); + fs.write(path, html) } - } - - - })(); \ No newline at end of file diff --git a/templates/default/static/styles/jsdoc-default.css b/templates/default/static/styles/jsdoc-default.css index 0cf7841f..2bf38c54 100644 --- a/templates/default/static/styles/jsdoc-default.css +++ b/templates/default/static/styles/jsdoc-default.css @@ -1,233 +1,155 @@ -.kind { font-style: italic; } - -.constructor, .mixin, .namespace +body { - font-weight: bold; - color: #780000; + font-family: "Lucida Grande", "Lucida Sans Unicode", "Lucida Sans", Verdana, Tahoma, sans-serif; + font-size: 13px; + color: #000; + background-color: #E2ECF0; } -.property { color: #666; } -.function { color: #666; } -.access { color: #666; } - -h1, h2, h3, h4, h5, h6 +header { - font-family: "Bitstream Vera Sans", "DejaVu Sans", "Trebuchet MS", Verdana, "Verdana Ref", sans serif; - font-weight: bold; + display: block; + /*border-bottom: 1px solid #ddd;*/ + padding: 6px 4px; } -.page-title -{ - font-family: "Bitstream Vera Sans", "DejaVu Sans", "Trebuchet MS", Verdana, "Verdana Ref", sans serif; - font-size: 3.5em; - font-weight: bolder; - margin: 0 0 0.1em; - color: #FFF; -} - -.section-title -{ - font-size: 2.5em; - margin: 0; - color: #798D3E; +.class-description { + font-style: italic; + font-family: Palatino, "Palatino Linotype", serif; + font-size: 18px; } section { - border: 1px solid #ccc; - border-radius: 15px; - -moz-border-radius: 8px; display: block; - padding: 0.75em 0.5em 0.5em 1em; - margin: 0.5em 0.5em 1em 1em; + margin: 14px 28px; + background-color: #fff; + padding: 12px 24px; + -moz-border-radius: 7px; + border-radius: 7px +} + +h1 +{ + font-size: 32px; + font-weight: bold; + letter-spacing: -0.03em; + margin: 6px 0 9px 0; +} + +h2 +{ + font-size: 22px; + font-weight: bold; + letter-spacing: -0.03em; + margin: 6px 0 3px 0; +} + +h3 +{ + font-size: 20px; + font-weight: bold; + letter-spacing: -0.03em; + margin-top: 16px; + margin: 6px 0 3px 0; +} + +h4 +{ + font-size: 18px; + font-weight: bold; + letter-spacing: -0.03em; + margin-top: 16px; + margin: 18px 0 3px 0; + color: #A35A00; +} + +h5 +{ + font-size: 16px; + font-weight: bold; + letter-spacing: -0.03em; + margin: 6px 0 3px 0; +} + +h6 +{ + font-size: 13px; + letter-spacing: -0.03em; + margin: 6px 0 3px 0; + font-style: italic; +} + +.ancestor-name { + color: #ccc; +} + +.type-signature { + color: #aaa; +} + +/*.description { + font-family: Palatino, "Palatino Linotype", serif; + font-size: 14px; +}*/ + +.code-caption +{ + font-style: italic; + font-family: Palatino, "Palatino Linotype", serif; + font-size: 14px; + margin: 0; +} + +.sh_sourceCode +{ + border: 1px solid #ddd; + width: 80%; +} + +.sh_sourceCode code +{ + font-family: Consolas, "Lucida Console", Monaco, monospace; + font-size: 12px; + line-height: 18px; + display: block; + padding: 4px 12px; + margin: 0; background-color: #fff; color: #000; + border-left: 3px #1C02A3 solid; } -.subsection-title +.params { - font-size: 1.9em; - margin: 0.5em 0 1em; - color: #000; + border-spacing: 0; + border: 0; + border-collapse: collapse; } -.method-title, .class-title +.params .name { color: #1C02A3; } + +.params td, .params th { - font-size: 1.7em; - margin: 0 0 1em 1em; - color: #7B1A3F; + border: 1px solid #ddd; + margin: 0px; + text-align: left; + vertical-align: top; + padding: 4px 6px; + display: table-cell; } -.detail-list { list-style-type: none; } - -html +.params thead tr { - /* stops IE resizing fonts by a massive amount */ - font-size: 100%; -} - -body -{ - /* fixes monospace font sizes in webkit */ - /* following line is picked up by IE6 & 7, which cannot resize pixel-based font sizes */ - *font-size: 62.5%; - font-size: 0.8em; - font-family: verdana, sans-serif; - /*overflow: hidden;*/ - zoom: 1; - /*background: url(images/pagebg.png) 0 73px repeat-x;*/ - color: #eee; - background-color: #22252a; -} - -a:link, a:visited -{ - color: #356a8b; - text-decoration: none; - border-bottom: 1px dotted #356a8b; -} - -a:hover, a:active -{ - color: #298FB2; - border-color: #298FB2; - border-bottom-style: solid; -} - -a.image { border: 0; } - -p -{ - margin: 0 0 1em 0; - line-height: 1.5; -} - -code { font-family: Consolas, "Andale Mono WT", "Andale Mono", "Lucida Console", "Lucida Sans Typewriter", "DejaVu Sans Mono", "Bitstream Vera Sans Mono", "Liberation Mono", "Nimbus Mono L", Monaco, "Courier New", Courier, monospace; } - -dl.params dt -{ - border-top: 1px solid #b2b1b1; - color: #298FB2; + background-color: #ddd; font-weight: bold; - padding-top: 8px; - margin-bottom: 5px; - font-size: 1.1em; - float: none; - overflow: visible; - zoom: 0; } -dl.params dt.first +.params .params thead tr { - border-top: none; - padding-top: 0; - margin-top: 0; -} - -dl.params dd -{ - border-width: 0; - margin-bottom: 16px; -} - -dl.param-properties -{ - font-style: italic; - overflow: hidden; - zoom: 1; - font-size: 0.9em; - margin: 1em 0; -} - -dl.param-properties dt span, -dl.param-properties dd -{ - color: #555; - float: left; - margin: 0; - padding: 0; - display: inline; - margin-bottom: 5px; - font-size: 1em; - border: none; -} - -dl.param-properties dt -{ - clear: both; - display: inline; - font-size: 1em; - padding: 0; - float: none; - overflow: visible; - zoom: 0; -} - -dl.param-properties dt span -{ - width: 85px; - clear: both; -} - -.no-docs -{ - font-style: italic; - font-weight: lighter; - color: #666; -} - -.property { margin-left: 30px; } - -.property-head -{ - margin-left: -20px; - display: block; - line-height: 1.2em; -} - -.property-name -{ - float: left; - margin: 0; - padding: 0 10px 0 0; - font-style: italic; + background-color: #fff; font-weight: bold; - font-size: 1.2em; - color: #4782B5; } -.property-summary -{ - color: #999; - font-size: 1em; -} - -.property-details -{ - clear: both; - overflow: hidden; -} - -.property-details dt -{ - font-weight: bold; - margin-bottom: 4px; - padding-left: 10px; - clear: left; - float: left; -} - -.property-details dd { padding-left: 60px; } -.property-deprecated { text-decoration: line-through; } - -.example-code -{ - padding: 2px 2px 2px 10px; - margin-right: 24px; - color: #fff; - background-color: #444; - border-radius: 2px; - -moz-border-radius: 2px; -} - -.yesDef { text-indent: -5000px; } \ No newline at end of file +.params th { border-right: 1px solid #aaa; } +.params thead .last { border-right: 1px solid #ddd; } \ No newline at end of file diff --git a/templates/default/static/styles/node-dark.css b/templates/default/static/styles/node-dark.css index 234e127d..5849e234 100644 --- a/templates/default/static/styles/node-dark.css +++ b/templates/default/static/styles/node-dark.css @@ -1,26 +1,150 @@ -.sh_sourceCode { - + .sh_sourceCode { + background-color: #ffffff; + color: #000000; font-weight: normal; font-style: normal; } -.sh_sourceCode .sh_symbol , .sh_sourceCode .sh_cbracket { - color: #fff; + .sh_sourceCode .sh_keyword { + color: #000000; + font-weight: bold; + font-style: normal; } -.sh_sourceCode .sh_keyword -{ - font-style: italic; - color: #ECDDAA; + .sh_sourceCode .sh_type { + color: #a52a2a; + font-weight: bold; + font-style: normal; } -.sh_sourceCode .sh_string, .sh_sourceCode .sh_regexp, .sh_sourceCode .sh_number, -.sh_sourceCode .sh_specialchar -{ - color: #B0C4DE; + .sh_sourceCode .sh_string { + color: #006400; + font-weight: normal; + font-style: normal; } -.sh_sourceCode .sh_comment { - color: #777; + .sh_sourceCode .sh_regexp { + color: #006400; + font-weight: normal; + font-style: normal; } + .sh_sourceCode .sh_specialchar { + color: #2e8b57; + font-weight: normal; + font-style: normal; +} + + .sh_sourceCode .sh_comment { + color: #000000; + font-weight: normal; + font-style: italic; +} + + .sh_sourceCode .sh_number { + color: #006400; + font-weight: normal; + font-style: normal; +} + + .sh_sourceCode .sh_preproc { + color: #27408b; + font-weight: normal; + font-style: normal; +} + + .sh_sourceCode .sh_symbol { + color: #000000; + font-weight: bold; + font-style: normal; +} + + .sh_sourceCode .sh_function { + color: #000000; + font-weight: normal; + font-style: normal; +} + + .sh_sourceCode .sh_cbracket { + color: #000000; + font-weight: bold; + font-style: normal; +} + + .sh_sourceCode .sh_url { + color: #006400; + font-weight: normal; + font-style: normal; +} + + .sh_sourceCode .sh_date { + color: #000000; + font-weight: bold; + font-style: normal; +} + + .sh_sourceCode .sh_time { + color: #000000; + font-weight: bold; + font-style: normal; +} + + .sh_sourceCode .sh_file { + color: #000000; + font-weight: bold; + font-style: normal; +} + + .sh_sourceCode .sh_ip { + color: #006400; + font-weight: normal; + font-style: normal; +} + + .sh_sourceCode .sh_name { + color: #006400; + font-weight: normal; + font-style: normal; +} + + .sh_sourceCode .sh_variable { + color: #dda0dd; + font-weight: bold; + font-style: normal; +} + + .sh_sourceCode .sh_oldfile { + color: #2e8b57; + font-weight: normal; + font-style: normal; +} + + .sh_sourceCode .sh_newfile { + color: #006400; + font-weight: normal; + font-style: normal; +} + + .sh_sourceCode .sh_difflines { + color: #000000; + font-weight: bold; + font-style: normal; +} + + .sh_sourceCode .sh_selector { + color: #dda0dd; + font-weight: bold; + font-style: normal; +} + + .sh_sourceCode .sh_property { + color: #000000; + font-weight: bold; + font-style: normal; +} + + .sh_sourceCode .sh_value { + color: #006400; + font-weight: normal; + font-style: normal; +} diff --git a/templates/default/tmpl/classes.mustache b/templates/default/tmpl/classes.mustache deleted file mode 100644 index 819548df..00000000 --- a/templates/default/tmpl/classes.mustache +++ /dev/null @@ -1,10 +0,0 @@ -
-{{#classes}} -
-

{{name}}

-
-
- {{#summary}}

{{{summary}}}

{{/summary}} -
-{{/classes}} -
diff --git a/templates/default/tmpl/container.mustache b/templates/default/tmpl/container.mustache deleted file mode 100644 index 34692572..00000000 --- a/templates/default/tmpl/container.mustache +++ /dev/null @@ -1,82 +0,0 @@ -{{%ARRAY-ORDINALS}} - - - - - JSDoc: {{title}} - - - - - - - - - - - -

{{title}}

- -{{#docs}} -
-

{{kind}}: {{name}}

- - {{#classdesc}} -
{{classdesc}}
- {{/classdesc}} - - {{#summary}} -
{{summary}}
- {{/summary}} - - {{#description}} -
{{description}}
- {{/description}} - - {{#hasConstructor}} -

Constructor:

-
- {{>methodsTemplate}} -
- {{/hasConstructor}} - - {{#hasClasses}} -

Classes:

- {{>classesTemplate}} - {{/hasClasses}} - - {{#hasNamespaces}} -

Namespaces:

- {{>namespacesTemplate}} - {{/hasNamespaces}} - -

Methods:

- {{#hasMethods}} -
- {{#methods}} - {{>methodsTemplate}} - {{/methods}} -
- {{/hasMethods}} - {{^hasMethods}} -

The {{name}} {{kind}} has no documented methods.

- {{/hasMethods}} - -

Properties:

- {{#hasProperties}} -
- {{#properties}} - {{>propertiesTemplate}} - {{/properties}} -
- {{/hasProperties}} - {{^hasProperties}} -

The {{name}} {{kind}} has no documented properties.

- {{/hasProperties}} - -
-{{/docs}} - - - - \ No newline at end of file diff --git a/templates/default/tmpl/container.tmpl b/templates/default/tmpl/container.tmpl new file mode 100644 index 00000000..9f874e77 --- /dev/null +++ b/templates/default/tmpl/container.tmpl @@ -0,0 +1,176 @@ + + + + + JSDoc: <?js= title ?> + + + + + + + + + + + + +

+ + +
+ +
+ '+doc.classdesc+'

'); + } + ?> + + +
+ +
+ + + + + + +

Extends

+ +
    +
  • +
+ + + + + +

Borrows From

+ +
    +
  • +
+ + + + + +

Classes

+ +
+
+
+
+ + + + + +

Namespaces

+ +
+
+
+
+ + + + + +

Properties

+ +
+ + + + + +

Methods

+ +
+ + + + + +

Events

+ +
+ + +
+
+ + + + + + + \ No newline at end of file diff --git a/templates/default/tmpl/example.mustache b/templates/default/tmpl/example.mustache deleted file mode 100644 index 089ac843..00000000 --- a/templates/default/tmpl/example.mustache +++ /dev/null @@ -1,12 +0,0 @@ -
-
Example
-
-
- {{#examples}} -
-
-
{{.}}
-
-
- {{/examples}} -
diff --git a/templates/default/tmpl/example.tmpl b/templates/default/tmpl/example.tmpl new file mode 100644 index 00000000..47a10889 --- /dev/null +++ b/templates/default/tmpl/example.tmpl @@ -0,0 +1,2 @@ + +
diff --git a/templates/default/tmpl/examples.tmpl b/templates/default/tmpl/examples.tmpl new file mode 100644 index 00000000..fdf78762 --- /dev/null +++ b/templates/default/tmpl/examples.tmpl @@ -0,0 +1,10 @@ + +

+ +
+ \ No newline at end of file diff --git a/templates/default/tmpl/exceptions.mustache b/templates/default/tmpl/exceptions.mustache deleted file mode 100644 index 3ff8169b..00000000 --- a/templates/default/tmpl/exceptions.mustache +++ /dev/null @@ -1,28 +0,0 @@ -
- {{#exceptions}} - - - -
-
- {{#type}} -
- Type -
-
- {{#names}} - {{#linkTo}}{{.}}{{/linkTo}}{{^last?}} | {{/last?}}{{#last?}} {{/last?}} - {{/names}} -
- {{/type}} -
- - {{#description}} -
- {{description}} -
- {{/description}} -
- - {{/exceptions}} -
\ No newline at end of file diff --git a/templates/default/tmpl/exceptions.tmpl b/templates/default/tmpl/exceptions.tmpl new file mode 100644 index 00000000..e4449867 --- /dev/null +++ b/templates/default/tmpl/exceptions.tmpl @@ -0,0 +1,28 @@ +
  • + +
    + +
    + + + +
    +
    + Type +
    +
    + + + +
    +
    + +
  • \ No newline at end of file diff --git a/templates/default/tmpl/fires.tmpl b/templates/default/tmpl/fires.tmpl new file mode 100644 index 00000000..1eef451f --- /dev/null +++ b/templates/default/tmpl/fires.tmpl @@ -0,0 +1,3 @@ +
  • + +
  • \ No newline at end of file diff --git a/templates/default/tmpl/index.mustache b/templates/default/tmpl/index.mustache deleted file mode 100644 index 88819e65..00000000 --- a/templates/default/tmpl/index.mustache +++ /dev/null @@ -1,189 +0,0 @@ -{{%ARRAY-ORDINALS}} - - - - - JSDoc Index - - - - - -

    {{title}}

    - -
    -{{#docs}} -

    - {{#kind}}{{kind}} {{/kind}}{{#access}}<{{access}}> {{/access}}{{longname}} - - {{#summary}}{{{summary}}}{{/summary}} - -

    -
    - -
    - {{#description}} -
    - {{{description}}} -
    - {{/description}} - - {{#hasBorrowed}} -

    Mixes In:

    -
      - {{#borrowed}}
    1. {{#linkTo}}{{from}}{{/linkTo}}
    2. {{/borrowed}} -
    - {{/hasBorrowed}} - - {{#hasParams}} -

    Parameters:

    - {{>paramsTemplate}} - {{/hasParams}} - - {{#hasReturns}} -

    Returns:

    - {{>returnsTemplate}} - {{/hasReturns}} -
    -
    -{{/docs}} - - - - \ No newline at end of file diff --git a/templates/default/tmpl/method.tmpl b/templates/default/tmpl/method.tmpl new file mode 100644 index 00000000..7bc5eccc --- /dev/null +++ b/templates/default/tmpl/method.tmpl @@ -0,0 +1,65 @@ + +
    +

    + + +

    + +
    +
    + + +
    Description:
    +

    + +

    + + + Parameters:'); + print( render('params.tmpl', params) ); + } + ?> + + +
    Fires:
    +
    + + + +
    Throws:
    +
    + + + Returns:'); + print('

    '+rdesc.join('

    ')+'

    '); + } + } + ?> + + Example' + (examples.length > 1? 's':'') + ''); + print( render('examples.tmpl', examples) ); + } + ?> + +
    diff --git a/templates/default/tmpl/methods.mustache b/templates/default/tmpl/methods.mustache deleted file mode 100644 index b7e621b8..00000000 --- a/templates/default/tmpl/methods.mustache +++ /dev/null @@ -1,33 +0,0 @@ - -
    -

    {{name}}

    -
    -
    - {{#summary}}

    {{{summary}}}

    {{/summary}} - -
    - -
    Synopsis:
    -
    {{synopsis}}
    - - {{#hasParams}} -
    Parameters:
    - {{>paramsTemplate}} - {{/hasParams}} - - {{#hasExceptions}} -
    Throws:
    - {{>exceptionsTemplate}} - {{/hasExceptions}} - - {{#hasReturns}} -
    Returns:
    - {{>returnsTemplate}} - {{/hasReturns}} - - {{#hasExamples}} - {{>examplesTemplate}} - {{/hasExamples}} -
    -
    - diff --git a/templates/default/tmpl/namespaces.mustache b/templates/default/tmpl/namespaces.mustache deleted file mode 100644 index a42cc1a6..00000000 --- a/templates/default/tmpl/namespaces.mustache +++ /dev/null @@ -1,10 +0,0 @@ -
    -{{#namespaces}} -
    -

    {{name}}

    -
    -
    - {{#summary}}

    {{{summary}}}

    {{/summary}} -
    -{{/namespaces}} -
    diff --git a/templates/default/tmpl/params.mustache b/templates/default/tmpl/params.mustache deleted file mode 100644 index 5b8e8d90..00000000 --- a/templates/default/tmpl/params.mustache +++ /dev/null @@ -1,53 +0,0 @@ -
    - {{#params}} - - -
    {{name}}
    - - -
    -
    - {{#type}} -
    - Type -
    -
    - {{#names}} - {{#linkTo}}{{.}}{{/linkTo}}{{^last?}} | {{/last?}}{{#last?}} {{/last?}} - {{/names}} -
    - - {{#defaultvalue}} -
    - Default -
    -
    - {{defaultvalue}} -
    - {{/defaultvalue}} - - {{#optional}} -
    - Optional -
    -
    Yes
    - {{/optional}} - - {{#nullable}} -
    - Nullable -
    -
    Yes
    - {{/nullable}} - {{/type}} -
    - - {{#description}} -
    - {{description}} -
    - {{/description}} -
    - - {{/params}} -
    \ No newline at end of file diff --git a/templates/default/tmpl/params.tmpl b/templates/default/tmpl/params.tmpl new file mode 100644 index 00000000..86575693 --- /dev/null +++ b/templates/default/tmpl/params.tmpl @@ -0,0 +1,115 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeArgumentDefaultDescription
    + + +
    ' ); + } + + if (param.nullable) { + print( '<nullable>
    ' ); + } + ?> +
    + + Properties' + render('params.tmpl', param.subparams) ); + }?>
    \ No newline at end of file diff --git a/templates/default/tmpl/properties.mustache b/templates/default/tmpl/properties.mustache deleted file mode 100644 index 341b5384..00000000 --- a/templates/default/tmpl/properties.mustache +++ /dev/null @@ -1,88 +0,0 @@ -
    - -
    -
    - {{name}} -
    -
    - {{{summary}}} -
    -
    -
    - {{#description}} -
    - Description -
    -
    - {{{description}}} -
    -
    - {{/description}} - - {{#deprecated}} -
    - Deprecated -
    -
    - {{{deprecated}}} -
    -
    - {{/deprecated}} - - {{#since}} -
    - Since -
    -
    - {{{since}}} -
    -
    - {{/since}} - - {{#type}} -
    - Type -
    -
    - {{#names}} - {{#linkTo}}{{.}}{{/linkTo}}{{^last?}} | {{/last?}}{{#last?}} {{/last?}} - {{/names}} -
    -
    - {{/type}} - - {{#readonly}} -
    - Readonly -
    -
    - Yes -
    -
    - {{/readonly}} - - {{#nullable}} -
    - Nullable -
    -
    - Yes -
    -
    - {{/nullable}} - - {{#defaultvalue}} -
    - Default -
    -
    - {{defaultvalue}} -
    -
    - {{/defaultvalue}} - - {{#hasExamples}} - {{>examplesTemplate}} - {{/hasExamples} -
    -
    \ No newline at end of file diff --git a/templates/default/tmpl/properties.tmpl b/templates/default/tmpl/properties.tmpl new file mode 100644 index 00000000..b4950fe5 --- /dev/null +++ b/templates/default/tmpl/properties.tmpl @@ -0,0 +1,47 @@ + +
    +

    + + +

    + +
    +
    + +
    Description:
    +

    + +

    + + + +
    + +
    Deprecated
    +
    Yes
    + + + +
    Since
    +
    + + + +
    Read-Only
    +
    Yes
    + + + +
    Default Value
    +
    + +
    + + + Example' + (examples.length > 1? 's':'') + ''); + print( render('examples.tmpl', examples) ); + } + ?> +
    diff --git a/templates/default/tmpl/returns.mustache b/templates/default/tmpl/returns.mustache deleted file mode 100644 index c9d1dc69..00000000 --- a/templates/default/tmpl/returns.mustache +++ /dev/null @@ -1,28 +0,0 @@ -
    - {{#returns}} - - - -
    -
    - {{#type}} -
    - Type -
    -
    - {{#names}} - {{#linkTo}}{{.}}{{/linkTo}}{{^last?}} | {{/last?}}{{#last?}} {{/last?}} - {{/names}} -
    - {{/type}} -
    - - {{#description}} -
    - {{description}} -
    - {{/description}} -
    - - {{/returns}} -
    \ No newline at end of file diff --git a/templates/default/tmpl/returns.tmpl b/templates/default/tmpl/returns.tmpl new file mode 100644 index 00000000..464d67f0 --- /dev/null +++ b/templates/default/tmpl/returns.tmpl @@ -0,0 +1,31 @@ +
  • + +
    + +
    + + + + +
    +
    + Type +
    +
    + + + +
    +
    + +
  • \ No newline at end of file