From f37bd95c6cade59bb53dc3c07ac6afe49b9bec42 Mon Sep 17 00:00:00 2001
From: Michael Mathews
Date: Sat, 24 Sep 2011 21:26:09 +0100
Subject: [PATCH 1/3] Added support for @property tags in doclets that have
kinds, no template output yet.
---
rhino_modules/jsdoc/name.js | 42 +++++++++++++++++++
rhino_modules/jsdoc/src/handlers.js | 23 +++++++---
.../jsdoc/tag/dictionary/definitions.js | 16 ++++---
test/t/jsdoc/name.js | 8 ++++
4 files changed, 78 insertions(+), 11 deletions(-)
diff --git a/rhino_modules/jsdoc/name.js b/rhino_modules/jsdoc/name.js
index fcc56701..a75a123b 100644
--- a/rhino_modules/jsdoc/name.js
+++ b/rhino_modules/jsdoc/name.js
@@ -179,3 +179,45 @@ exports.shorten = function(longname) {
return {longname: longname, memberof: memberof, scope: scope, name: name, variation: variation};
}
+/**
+ Split a string that starts with a name and ends with a description, into its parts.
+ @param {string} nameDesc
+ @returns {object} Hash with "name" and "description" properties.
+ */
+exports.splitName = function(nameDesc) {
+ var name = '',
+ desc = '',
+ thisChar = '',
+ inQuote = false;
+
+ for (var i = 0, len = nameDesc.length; i < len; i++) {
+ thisChar = nameDesc.charAt(i);
+
+ if (thisChar === '\\') {
+ name += thisChar + nameDesc.charAt(++i);
+ continue;
+ }
+
+ if (thisChar === '"') {
+ inQuote = !inQuote;
+ }
+
+ if (inQuote) {
+ name += thisChar;
+ continue;
+ }
+
+ if (!inQuote) {
+ if ( /\s/.test(thisChar) ) {
+ desc = nameDesc.substr(i);
+ desc = desc.replace(/^[\s-\s]+/, '').trim();
+ break;
+ }
+ else {
+ name += thisChar;
+ }
+ }
+ }
+
+ return { name: name, description: desc };
+}
\ No newline at end of file
diff --git a/rhino_modules/jsdoc/src/handlers.js b/rhino_modules/jsdoc/src/handlers.js
index fd431ab6..a636954f 100644
--- a/rhino_modules/jsdoc/src/handlers.js
+++ b/rhino_modules/jsdoc/src/handlers.js
@@ -10,7 +10,7 @@ var currentModule = null;
@param parser
*/
exports.attachTo = function(parser) {
- var jsdoc = {doclet: require('jsdoc/doclet')};
+ var jsdoc = {doclet: require('jsdoc/doclet'), name: require('jsdoc/name')};
// handles JSDoc comments that include a @name tag -- the code is ignored in such a case
parser.on('jsdocCommentFound', function(e) {
@@ -40,11 +40,11 @@ exports.attachTo = function(parser) {
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) {
if (newDoclet.alias === '{@thisClass}') {
@@ -117,6 +117,17 @@ exports.attachTo = function(parser) {
return false;
}
+ // find name and description from each property tag text
+ if (newDoclet.properties) {
+ for (var i = 0, len = newDoclet.properties.length; i < len; i++) {
+ var property = newDoclet.properties[i];
+
+ var parts = jsdoc.name.splitName(property.description);
+ property.name = parts.name;
+ property.description = parts.description;
+ }
+ }
+
addDoclet.call(this, newDoclet);
e.doclet = newDoclet;
}
diff --git a/rhino_modules/jsdoc/tag/dictionary/definitions.js b/rhino_modules/jsdoc/tag/dictionary/definitions.js
index b1a70acd..99aca379 100644
--- a/rhino_modules/jsdoc/tag/dictionary/definitions.js
+++ b/rhino_modules/jsdoc/tag/dictionary/definitions.js
@@ -352,10 +352,16 @@ exports.defineTags = function(dictionary) {
dictionary.defineTag('property', {
canHaveType: true,
onTagged: function(doclet, tag) {
- setDocletKindToTitle(doclet, tag);
- setDocletNameToValue(doclet, tag);
- if (tag.value && tag.value.type) {
- doclet.type = tag.value.type;
+ if (doclet.kind) {
+ if (!doclet.properties) { doclet.properties = []; }
+ doclet.properties.push(tag.value);
+ }
+ else {
+ setDocletKindToTitle(doclet, tag);
+ setDocletNameToValue(doclet, tag);
+ if (tag.value && tag.value.type) {
+ doclet.type = tag.value.type;
+ }
}
}
})
@@ -400,7 +406,7 @@ exports.defineTags = function(dictionary) {
mustHaveValue: true,
canHaveType: true,
onTagged: function(doclet, tag) {
- if (!doclet.returns) { doclet.returns = []; }
+ if (!doclet.returns) { doclet.returns = []; }
doclet.returns.push(tag.value);
}
})
diff --git a/test/t/jsdoc/name.js b/test/t/jsdoc/name.js
index 570d144a..207c7573 100644
--- a/test/t/jsdoc/name.js
+++ b/test/t/jsdoc/name.js
@@ -117,3 +117,11 @@ test('The module:jsdoc/name.shorten function finds the variation.', function() {
assert.equal(parts.name, 'fadein');
assert.equal(parts.longname, 'anim.fadein(2)');
});
+
+test('The module:jsdoc/name.splitName function finds the name and description.', function() {
+ var startName = 'ns.Page#"last \\"sentence\\"".words~sort(2) - This is a description. ',
+ parts = jsdoc.name.splitName(startName);
+
+ assert.equal(parts.name, 'ns.Page#"last \\"sentence\\"".words~sort(2)');
+ assert.equal(parts.description, 'This is a description.');
+});
\ No newline at end of file
From 31161fc9b6380443ee05190d1ee98fba148e591e Mon Sep 17 00:00:00 2001
From: Michael Mathews
Date: Sat, 24 Sep 2011 21:52:35 +0100
Subject: [PATCH 2/3] Rename old @property tag to @member.
---
rhino_modules/jsdoc/doclet.js | 2 +-
rhino_modules/jsdoc/schema.js | 2 +-
.../jsdoc/tag/dictionary/definitions.js | 27 ++++++++++---------
templates/default/publish.js | 10 +++----
templates/default/tmpl/container.tmpl | 12 ++++-----
templates/default/tmpl/properties.tmpl | 24 -----------------
test/cases/memberoftag.js | 4 +--
test/cases/quotename.js | 2 +-
test/cases/typekind.js | 2 +-
9 files changed, 31 insertions(+), 54 deletions(-)
diff --git a/rhino_modules/jsdoc/doclet.js b/rhino_modules/jsdoc/doclet.js
index 66dd1177..a5f56a12 100644
--- a/rhino_modules/jsdoc/doclet.js
+++ b/rhino_modules/jsdoc/doclet.js
@@ -229,7 +229,7 @@ function codetypeToKind(type) {
var kind = (type || '').toLowerCase();
if (kind !== 'function') {
- return 'property';
+ return 'member';
}
return kind;
diff --git a/rhino_modules/jsdoc/schema.js b/rhino_modules/jsdoc/schema.js
index be52250f..5cbc85e2 100644
--- a/rhino_modules/jsdoc/schema.js
+++ b/rhino_modules/jsdoc/schema.js
@@ -100,7 +100,7 @@ exports.jsdocSchema = {
"kind": { // what kind of symbol is this?
"type": "string",
"maxItems": 1,
- "enum": ["constructor", "module", "event", "namespace", "method", "property", "enum", "class", "interface", "constant", "mixin", "file", "version"]
+ "enum": ["constructor", "module", "event", "namespace", "method", "member", "enum", "class", "interface", "constant", "mixin", "file", "version"]
},
"refersto": { // the path to another doc: this doc is simply a renamed alias to that
"type": "string",
diff --git a/rhino_modules/jsdoc/tag/dictionary/definitions.js b/rhino_modules/jsdoc/tag/dictionary/definitions.js
index 99aca379..af434849 100644
--- a/rhino_modules/jsdoc/tag/dictionary/definitions.js
+++ b/rhino_modules/jsdoc/tag/dictionary/definitions.js
@@ -292,8 +292,7 @@ exports.defineTags = function(dictionary) {
onTagged: function(doclet, tag) {
setDocletMemberof(doclet, tag);
}
- })
- .synonym('member');
+ });
dictionary.defineTag('mixin', {
onTagged: function(doclet, tag) {
@@ -352,20 +351,22 @@ exports.defineTags = function(dictionary) {
dictionary.defineTag('property', {
canHaveType: true,
onTagged: function(doclet, tag) {
- if (doclet.kind) {
- if (!doclet.properties) { doclet.properties = []; }
- doclet.properties.push(tag.value);
- }
- else {
- setDocletKindToTitle(doclet, tag);
- setDocletNameToValue(doclet, tag);
- if (tag.value && tag.value.type) {
- doclet.type = tag.value.type;
- }
+ if (!doclet.properties) { doclet.properties = []; }
+ doclet.properties.push(tag.value);
+ }
+ })
+ .synonym('prop');
+
+ dictionary.defineTag('member', {
+ canHaveType: true,
+ onTagged: function(doclet, tag) {
+ setDocletKindToTitle(doclet, tag);
+ setDocletNameToValue(doclet, tag);
+ if (tag.value && tag.value.type) {
+ doclet.type = tag.value.type;
}
}
})
- .synonym('prop')
.synonym('var');
dictionary.defineTag('protected', {
diff --git a/templates/default/publish.js b/templates/default/publish.js
index 4649cb04..7e278664 100644
--- a/templates/default/publish.js
+++ b/templates/default/publish.js
@@ -96,11 +96,11 @@
}
if (f.scope && f.scope !== 'instance') {
- if (f.kind == 'function' || f.kind == 'property') attribs.push(f.scope);
+ if (f.kind == 'function' || f.kind == 'member') attribs.push(f.scope);
}
if (f.readonly === true) {
- if (f.kind == 'property') attribs.push('readonly');
+ if (f.kind == 'member') attribs.push('readonly');
}
f.attribs = ''+htmlsafe(attribs.length? '<'+attribs.join(', ')+'> ' : '')+'';
@@ -126,7 +126,7 @@
addAttribs(doclet);
}
- if (doclet.kind === 'property') {
+ if (doclet.kind === 'member') {
addSignatureType(doclet);
addAttribs(doclet)
}
@@ -156,7 +156,7 @@
data.orderBy(['longname', 'version', 'since']);
// kinds of containers
- var globals = find( {kind: ['property', 'function'], memberof: {isUndefined: true}} ),
+ var globals = find( {kind: ['member', 'function'], memberof: {isUndefined: true}} ),
modules = find({kind: 'module'}),
externals = find({kind: 'external'}),
mixins = find({kind: 'mixin'}),
@@ -262,7 +262,7 @@
nav = nav + '';
}
- var globalNames = find({kind: ['property', 'function'], 'memberof': {'isUndefined': true}});
+ var globalNames = find({kind: ['member', 'function'], 'memberof': {'isUndefined': true}});
if (globalNames.length) {
nav = nav + 'Global
';
diff --git a/templates/default/tmpl/container.tmpl b/templates/default/tmpl/container.tmpl
index e4f213d4..ec405ce8 100644
--- a/templates/default/tmpl/container.tmpl
+++ b/templates/default/tmpl/container.tmpl
@@ -154,18 +154,18 @@
- Properties
+ Members
diff --git a/templates/default/tmpl/properties.tmpl b/templates/default/tmpl/properties.tmpl
index 91687252..e69de29b 100644
--- a/templates/default/tmpl/properties.tmpl
+++ b/templates/default/tmpl/properties.tmpl
@@ -1,24 +0,0 @@
-
--
-
-
-
-
-
-
--
-
-
-
-
-
-
-
-
- Example' + (examples.length > 1? 's':'') + '');
- print( render('examples.tmpl', examples) );
- }
- ?>
-
diff --git a/test/cases/memberoftag.js b/test/cases/memberoftag.js
index 2337c49f..27993933 100644
--- a/test/cases/memberoftag.js
+++ b/test/cases/memberoftag.js
@@ -1,9 +1,9 @@
/** @constructor
- @member mathlib
+ @memberof mathlib
*/
function Data() {
- /** @property */
+ /** @member */
this.point = {};
}
diff --git a/test/cases/quotename.js b/test/cases/quotename.js
index e484db5e..aa7577c1 100644
--- a/test/cases/quotename.js
+++ b/test/cases/quotename.js
@@ -8,7 +8,7 @@ chat["#channel"] = {};
/**
- @property
+ @member
@type {boolean}
@defaultvalue
*/
diff --git a/test/cases/typekind.js b/test/cases/typekind.js
index cc4c5450..687eb7d7 100644
--- a/test/cases/typekind.js
+++ b/test/cases/typekind.js
@@ -12,6 +12,6 @@ module.exports = require('connect').createServer(
);
/**
- @property {number} module:blog/server.port
+ @member {number} module:blog/server.port
@default 8080
*/
\ No newline at end of file
From 2e857fcecce38172e7a862ee7f5b0ada731d6480 Mon Sep 17 00:00:00 2001
From: Michael Mathews
Date: Mon, 26 Sep 2011 14:46:31 +0100
Subject: [PATCH 3/3] Added support for @enum. Rename old @property to @member.
---
rhino_modules/jsdoc/doclet.js | 3 +-
rhino_modules/jsdoc/name.js | 47 ++++---
rhino_modules/jsdoc/src/handlers.js | 4 +
rhino_modules/jsdoc/src/parser.js | 25 ++++
.../jsdoc/tag/dictionary/definitions.js | 23 +++-
rhino_modules/jsdoc/tag/type.js | 2 +-
.../default/static/styles/jsdoc-default.css | 16 +--
templates/default/tmpl/container.tmpl | 4 +-
templates/default/tmpl/details.tmpl | 13 ++
templates/default/tmpl/members.tmpl | 24 ++++
templates/default/tmpl/method.tmpl | 4 +-
templates/default/tmpl/properties.tmpl | 115 ++++++++++++++++++
test/cases/enum.js | 29 +++++
test/cases/memberoftagforced.js | 44 +++++++
test/cases/propertytag.js | 19 +++
test/t/cases/aliasglobal.js | 4 +-
test/t/cases/var.js | 4 +-
17 files changed, 345 insertions(+), 35 deletions(-)
create mode 100644 templates/default/tmpl/members.tmpl
create mode 100644 test/cases/enum.js
create mode 100644 test/cases/memberoftagforced.js
create mode 100644 test/cases/propertytag.js
diff --git a/rhino_modules/jsdoc/doclet.js b/rhino_modules/jsdoc/doclet.js
index a5f56a12..9ff06dc5 100644
--- a/rhino_modules/jsdoc/doclet.js
+++ b/rhino_modules/jsdoc/doclet.js
@@ -51,8 +51,9 @@ exports.Doclet.prototype.postProcess = function() {
this.setLongname(this.name);
}
if (this.memberof === '') {
- delete(this.memberof);
+ delete(this.memberof);
}
+
if (!this.kind && this.meta && this.meta.code) {
this.addTag( 'kind', codetypeToKind(this.meta.code.type) );
}
diff --git a/rhino_modules/jsdoc/name.js b/rhino_modules/jsdoc/name.js
index a75a123b..f0a17d6b 100644
--- a/rhino_modules/jsdoc/name.js
+++ b/rhino_modules/jsdoc/name.js
@@ -31,18 +31,18 @@ exports.resolve = function(doclet) {
name = doclet.longname = doclet.meta.code.funcscope + '~' + name;
}
- if (memberof) { // @memberof tag given
- memberof = memberof.replace(/\.prototype\.?/g, '#');
+ if (memberof || doclet.forceMemberof) { // @memberof tag given
+ memberof = ('' || memberof).replace(/\.prototype\.?/g, '#');
// the name is a fullname, like @name foo.bar, @memberof foo
if (name && name.indexOf(memberof) === 0) {
- about = exports.shorten(name);
+ about = exports.shorten(name, (doclet.forceMemberof? memberof : undefined));
}
else if (name && /([#.~])$/.test(memberof) ) { // like @memberof foo# or @memberof foo~
- about = exports.shorten(memberof + name);
+ about = exports.shorten(memberof + name, (doclet.forceMemberof? memberof : undefined));
}
else if (name && doclet.scope ) { // like @memberof foo# or @memberof foo~
- about = exports.shorten(memberof + scopeToPunc[doclet.scope] + name);
+ about = exports.shorten(memberof + (scopeToPunc[doclet.scope]||'') + name, (doclet.forceMemberof? memberof : undefined));
}
}
else { // no @memberof
@@ -67,7 +67,7 @@ exports.resolve = function(doclet) {
}
else if (about.scope) {
if (about.memberof === '') { // via @memberof ?
- delete doclet.scope;
+ doclet.scope = 'global';
}
else {
doclet.scope = puncToScope[about.scope];
@@ -130,9 +130,10 @@ exports.applyNamespace = function(longname, ns) {
Given a longname like "a.b#c(2)", slice it up into ["a.b", "#", 'c', '2'],
representing the memberof, the scope, the name, and variation.
@param {string} longname
+ @param {string} forcedMemberof
@returns {object} Representing the properties of the given name.
*/
-exports.shorten = function(longname) {
+exports.shorten = function(longname, forcedMemberof) {
// quoted strings in a longname are atomic, convert to tokens
var atoms = [], token;
@@ -149,18 +150,32 @@ exports.shorten = function(longname) {
return dot + token; // foo["bar"] => foo.@{1}@
});
-
- longname = longname.replace( /\.prototype\.?/g, '#' );
-
- var parts = longname?
- (longname.match( /^(:?(.+)([#.~]))?(.+?)$/ ) || []).reverse()
- : [''];
- var name = parts[0] || '', // ensure name is always initialised to avoid error being thrown when calling replace on undefined [gh-24]
- scope = parts[1] || '', // ., ~, or #
- memberof = parts[2] || '',
+ var name = '',
+ scope = '', // ., ~, or #
+ memberof = '',
variation;
+ longname = longname.replace( /\.prototype\.?/g, '#' );
+//console.log(forcedMemberof);
+ if (typeof forcedMemberof !== 'undefined') {
+//console.log('forcedMemberof');
+ name = longname.substr(forcedMemberof.length);
+ var parts = forcedMemberof.match(/^(.*?)([#.~]?)$/);
+//console.log(parts);
+ if (parts[1]) memberof = parts[1] || forcedMemberof;
+ if (parts[2]) scope = parts[2];
+ }
+ else {
+ var parts = longname?
+ (longname.match( /^(:?(.+)([#.~]))?(.+?)$/ ) || []).reverse()
+ : [''];
+
+ name = parts[0] || ''; // ensure name is always initialised to avoid error being thrown when calling replace on undefined [gh-24]
+ scope = parts[1] || ''; // ., ~, or #
+ memberof = parts[2] || '';
+ }
+
// like /** @name foo.bar(2) */
if ( /(.+)\(([^)]+)\)$/.test(name) ) {
name = RegExp.$1, variation = RegExp.$2;
diff --git a/rhino_modules/jsdoc/src/handlers.js b/rhino_modules/jsdoc/src/handlers.js
index a636954f..e53064ae 100644
--- a/rhino_modules/jsdoc/src/handlers.js
+++ b/rhino_modules/jsdoc/src/handlers.js
@@ -128,6 +128,10 @@ exports.attachTo = function(parser) {
}
}
+ if (!newDoclet.memberof) {
+ newDoclet.scope = 'global';
+ }
+
addDoclet.call(this, newDoclet);
e.doclet = newDoclet;
}
diff --git a/rhino_modules/jsdoc/src/parser.js b/rhino_modules/jsdoc/src/parser.js
index 0bca33a9..f29d4344 100644
--- a/rhino_modules/jsdoc/src/parser.js
+++ b/rhino_modules/jsdoc/src/parser.js
@@ -201,6 +201,23 @@ exports.Parser.prototype.resolveThis = function(node) {
}
}
+/**
+ Given: foo = { x:1 }, find foo from x.
+ */
+exports.Parser.prototype.resolvePropertyParent = function(node) {
+ var memberof = {};
+
+ if (node.parent) {
+ var parent = node.parent;
+ if (parent.type === Token.COLON) parent = parent.parent; // go up one more
+
+ memberof.id = 'astnode'+parent.hashCode();
+ memberof.doclet = this.refs[memberof.id];
+
+ if (memberof.doclet) { return memberof; }
+ }
+}
+
/**
* Resolve what function a var is limited to.
* @param {astnode} node
@@ -286,6 +303,14 @@ function visitNode(node) {
if (e.doclet) {
currentParser.refs['astnode'+e.code.node.hashCode()] = e.doclet; // allow lookup from value => doclet
}
+
+ var parent = currentParser.resolvePropertyParent(node);
+ if (parent && parent.doclet.isEnum) {
+ if (!parent.doclet.properties) { parent.doclet.properties = []; }
+ // members of an enum inherit the enum's type
+ if (parent.doclet.type && !e.doclet.type) { e.doclet.type = parent.doclet.type; }
+ parent.doclet.properties.push(e.doclet);
+ }
}
else if (node.type == Token.VAR || node.type == Token.LET || node.type == Token.CONST) {
diff --git a/rhino_modules/jsdoc/tag/dictionary/definitions.js b/rhino_modules/jsdoc/tag/dictionary/definitions.js
index af434849..8f00ac99 100644
--- a/rhino_modules/jsdoc/tag/dictionary/definitions.js
+++ b/rhino_modules/jsdoc/tag/dictionary/definitions.js
@@ -161,6 +161,15 @@ exports.defineTags = function(dictionary) {
})
.synonym('desc');
+ dictionary.defineTag('enum', {
+ canHaveType: true,
+ onTagged: function(doclet, tag) {
+ doclet.kind = 'member';
+ doclet.isEnum = true;
+ doclet.type = tag.value.type;
+ }
+ });
+
dictionary.defineTag('event', {
onTagged: function(doclet, tag) {
setDocletKindToTitle(doclet, tag);
@@ -290,9 +299,17 @@ exports.defineTags = function(dictionary) {
dictionary.defineTag('memberof', {
mustHaveValue: true,
onTagged: function(doclet, tag) {
+ if (tag.originalTitle === 'memberof!') {
+ doclet.forceMemberof = true;
+ if (tag.value === '') {
+ doclet.addTag('global');
+ delete doclet.memberof;
+ }
+ }
setDocletMemberof(doclet, tag);
}
- });
+ })
+ .synonym('memberof!');
dictionary.defineTag('mixin', {
onTagged: function(doclet, tag) {
@@ -544,7 +561,9 @@ function setNameToFile(doclet, tag) {
}
function setDocletMemberof(doclet, tag) {
- doclet.setMemberof(tag.value);
+ if (tag.value && tag.value !== '') {
+ doclet.setMemberof(tag.value);
+ }
}
function applyNamespace(doclet, tag) {
diff --git a/rhino_modules/jsdoc/tag/type.js b/rhino_modules/jsdoc/tag/type.js
index 457e1607..812d7fbd 100644
--- a/rhino_modules/jsdoc/tag/type.js
+++ b/rhino_modules/jsdoc/tag/type.js
@@ -107,5 +107,5 @@ function parseTypes(type) {
/** @private */
function trim(text) {
- return text.replace(/^\s+|\s+$/g, '');
+ return text.trim();
}
diff --git a/templates/default/static/styles/jsdoc-default.css b/templates/default/static/styles/jsdoc-default.css
index ad82e701..e00cb000 100644
--- a/templates/default/static/styles/jsdoc-default.css
+++ b/templates/default/static/styles/jsdoc-default.css
@@ -134,7 +134,7 @@ h4
color: #A35A00;
}
-h5
+h5, .container-overview .subsection-title
{
font-size: 16px;
font-weight: bold;
@@ -203,16 +203,16 @@ h6
border-left: 3px #ddd solid;
}
-.params
+.params, .props
{
border-spacing: 0;
border: 0;
border-collapse: collapse;
}
-.params .name { color: #1C02A3; }
+.params .name, .props .name { color: #1C02A3; }
-.params td, .params th
+.params td, .params th, .props td, .props th
{
border: 1px solid #ddd;
margin: 0px;
@@ -222,17 +222,17 @@ h6
display: table-cell;
}
-.params thead tr
+.params thead tr, .props thead tr
{
background-color: #ddd;
font-weight: bold;
}
-.params .params thead tr
+.params .params thead tr, .props .props thead tr
{
background-color: #fff;
font-weight: bold;
}
-.params th { border-right: 1px solid #aaa; }
-.params thead .last { border-right: 1px solid #ddd; }
\ No newline at end of file
+.params th, .props th { border-right: 1px solid #aaa; }
+.params thead .last, .props thead .last { border-right: 1px solid #ddd; }
\ No newline at end of file
diff --git a/templates/default/tmpl/container.tmpl b/templates/default/tmpl/container.tmpl
index ec405ce8..64f6a8b0 100644
--- a/templates/default/tmpl/container.tmpl
+++ b/templates/default/tmpl/container.tmpl
@@ -46,7 +46,8 @@
?>
-
+
+
+
+
+
+ Properties:
+
+
+
+
+
- Version:
diff --git a/templates/default/tmpl/members.tmpl b/templates/default/tmpl/members.tmpl
new file mode 100644
index 00000000..49c4a1eb
--- /dev/null
+++ b/templates/default/tmpl/members.tmpl
@@ -0,0 +1,24 @@
+
+-
+
+
+
+
+
+
+-
+
+
+
+
+
+
+
+
+ Example' + (examples.length > 1? 's':'') + '');
+ print( render('examples.tmpl', examples) );
+ }
+ ?>
+
diff --git a/templates/default/tmpl/method.tmpl b/templates/default/tmpl/method.tmpl
index 3a51984c..8f615380 100644
--- a/templates/default/tmpl/method.tmpl
+++ b/templates/default/tmpl/method.tmpl
@@ -13,8 +13,6 @@
-
-
This:');
@@ -29,6 +27,8 @@
}
?>
+
+
Fires:
+
+
+
+
+
+ | Name |
+
+
+ Type |
+
+
+ Argument |
+
+
+
+ Default |
+
+
+ Description |
+
+
+
+
+
+
+
+
+ |
+
+
+
+
+ |
+
+
+
+ ' );
+ }
+
+ if (prop.nullable) {
+ print( '<nullable> ' );
+ }
+ ?>
+ |
+
+
+
+
+
+ |
+
+
+ Properties' + render('properties.tmpl', prop.subprops) );
+ }?> |
+
+
+
+
+
\ No newline at end of file
diff --git a/test/cases/enum.js b/test/cases/enum.js
new file mode 100644
index 00000000..0cc95d0e
--- /dev/null
+++ b/test/cases/enum.js
@@ -0,0 +1,29 @@
+
+/** @constructor */
+function Data() {
+
+ /**
+ The current position.
+ @enum {number}
+ */
+ this.point = {
+ /** The x coordinate of the point. */
+ x: 0,
+
+ /** The y coordinate of the point. */
+ y: 0
+ };
+}
+
+/**
+ * Enum for tri-state values.
+ * @enum {number}
+ */
+TriState = {
+ /** true */
+ TRUE: 1,
+ /** false */
+ FALSE: -1,
+ /** @type {boolean} */
+ MAYBE: true
+};
\ No newline at end of file
diff --git a/test/cases/memberoftagforced.js b/test/cases/memberoftagforced.js
new file mode 100644
index 00000000..c1b495de
--- /dev/null
+++ b/test/cases/memberoftagforced.js
@@ -0,0 +1,44 @@
+
+ /** @constructor
+ */
+ function Data() {
+
+ /**
+ The current position.
+ @type {object}
+ @property {boolean} needsRevalidate Does this point need to be revalidated?
+ */
+ this.point = {
+ /**
+ The x coordinate of the point.
+ @type {number}
+ @name point.x
+ @memberof! Data#
+ */
+ x: 0,
+
+ /**
+ The y coordinate of the point.
+ @type {number}
+ @name point.y
+ @memberof! Data#
+ @see {@link Data#point.x}
+ */
+ y: 0,
+
+ needsRevalidate: false
+ };
+ }
+
+var map = {
+ /**
+ @type {Array}
+ @name map.routes
+ @memberof!
+ @property {Data#point} point
+ */
+ routes: []
+}
+
+/** The current cursor. */
+var cursor = {};
\ No newline at end of file
diff --git a/test/cases/propertytag.js b/test/cases/propertytag.js
new file mode 100644
index 00000000..7b9a1cb8
--- /dev/null
+++ b/test/cases/propertytag.js
@@ -0,0 +1,19 @@
+/**
+ * @namespace
+ * @property {Object} defaults The default values.
+ * @property {Number} defaults.a The a property of the defaults.
+ * @property {String} defaults.b The b property of the defaults.
+ */
+myobject = {
+ defaults: {
+ a: 1,
+ b: "Hit the light",
+ /**
+ * The c property of the defaults.
+ * @member
+ * @type {Boolean}
+ * @property {String} prop The property of c.
+ */
+ c: true
+ }
+};
\ No newline at end of file
diff --git a/test/t/cases/aliasglobal.js b/test/t/cases/aliasglobal.js
index 2e7b4fe6..c0f6680a 100644
--- a/test/t/cases/aliasglobal.js
+++ b/test/t/cases/aliasglobal.js
@@ -2,8 +2,8 @@
var docSet = testhelpers.getDocSetFromFile('test/cases/aliasglobal.js'),
log = docSet.getByLongname('log')[0];
- test('When a symbol is documented as a static member of it is not static.', function() {
- assert.equal(typeof log.scope, 'undefined');
+ test('When a symbol is documented as a static member of it\'s scope is "global" and not "static".', function() {
+ assert.equal(log.scope, 'global');
});
})();
\ No newline at end of file
diff --git a/test/t/cases/var.js b/test/t/cases/var.js
index deb31faa..c7736daa 100644
--- a/test/t/cases/var.js
+++ b/test/t/cases/var.js
@@ -13,7 +13,7 @@
assert.equal(found[0][0].comment, '/** document me */', 'The first constant should get the docs.');
assert.equal(found[0][0].name, 'GREEN', 'The short name should be correct.');
assert.equal(found[0][0].memberof, undefined, 'The memberof should be undefined.');
- assert.equal(found[0][0].scope, undefined, 'The scope should be undefined.');
+ assert.equal(found[0][0].scope, 'global', 'The scope should be global.');
assert.equal(found[1].length, 1, 'The second constant should be found');
assert.equal(found[1][0].undocumented, true, 'The second constant should not get the docs.');
@@ -23,7 +23,7 @@
assert.equal(found[4][0].comment, '/** document me */', 'The correct var should get the docs.');
assert.equal(found[4][0].name, 'results', 'The short name should be correct.');
assert.equal(found[4][0].memberof, undefined, 'The memberof should be undefined.');
- assert.equal(found[4][0].scope, undefined, 'The scope should be undefined.');
+ assert.equal(found[4][0].scope, 'global', 'The scope should be global.');
});
})();
\ No newline at end of file