link to type applications correctly in template output (#152)

This commit is contained in:
Jeff Williams 2013-03-19 22:43:27 -07:00
parent 70bea4648e
commit edcd94eeba
2 changed files with 56 additions and 1 deletions

View File

@ -100,11 +100,42 @@ var tutorialLinkMap = {
var longnameToUrl = exports.longnameToUrl = linkMap.longnameToUrl;
/**
* Retrieve an HTML link to the member with the specified longname. If the longname is not
* associated with a URL, this method returns the link text, if provided, or the longname.
*
* This method supports type applications that can contain one or more types, such as
* `Array.<MyClass>` or `Array.<(MyClass|YourClass)>`. In these examples, the method attempts to
* replace `Array`, `MyClass`, and `YourClass` with links to the appropriate types. The link text
* is ignored for type applications.
*
* @param {string} longname - The longname that is the target of the link.
* @param {string=} linktext - The text to display for the link, or `longname` if no text is
* provided.
* @param {string=} cssClass - The CSS class (or classes) to include in the link's `<a>` tag.
* @return {string} The HTML link, or a plain-text string if the link is not available.
*/
var linkto = exports.linkto = function(longname, linktext, cssClass) {
var catharsis = require('catharsis');
var classString = cssClass ? util.format(' class="%s"', cssClass) : '';
var text = linktext || longname;
var url = hasOwnProp.call(longnameToUrl, longname) && longnameToUrl[longname];
var parsedType;
// type applications require special treatment
var typeAppInfo = /(\S+)<(\S+)>/.exec(longname);
if (typeAppInfo) {
typeAppInfo[1] = linkto(typeAppInfo[1], null, cssClass);
parsedType = catharsis.parse(typeAppInfo[2], {jsdoc: true});
typeAppInfo[2] = catharsis.stringify(parsedType, {
cssClass: cssClass,
htmlSafe: true,
links: longnameToUrl
});
return typeAppInfo[1] + '&lt;' + typeAppInfo[2] + '>';
}
if (!url) {
return text;
}

View File

@ -223,10 +223,12 @@ describe("jsdoc/util/templateHelper", function() {
describe("linkto", function() {
beforeEach(function() {
helper.longnameToUrl.linktoTest = 'test.html';
helper.longnameToUrl.LinktoFakeClass = 'fakeclass.html';
});
afterEach(function() {
delete helper.longnameToUrl.linktoTest;
delete helper.longnameToUrl.LinktoFakeClass;
});
it('returns the longname if only the longname is specified and has no URL', function() {
@ -260,12 +262,34 @@ describe("jsdoc/util/templateHelper", function() {
expect(link).toBe('<a href="test.html" class="myclass">link text</a>');
});
it("is careful with longnames that are reserved words in JS", function() {
it('is careful with longnames that are reserved words in JS', function() {
// we don't have a registered link for 'constructor' so it should return the text 'link text'.
var link = helper.linkto('constructor', 'link text');
expect(typeof link).toBe('string');
expect(link).toBe('link text');
});
it('works correctly with type applications if only the longname is specified', function() {
var link = helper.linkto('Array.<LinktoFakeClass>');
expect(link).toBe('Array.&lt;<a href="fakeclass.html">LinktoFakeClass</a>>');
});
it('works correctly with type applications if a class is not specified', function() {
var link = helper.linkto('Array.<LinktoFakeClass>', 'link text');
expect(link).toBe('Array.&lt;<a href="fakeclass.html">LinktoFakeClass</a>>');
});
it('works correctly with type applications if a class is specified', function() {
var link = helper.linkto('Array.<LinktoFakeClass>', 'link text', 'myclass');
expect(link).toBe('Array.&lt;<a href="fakeclass.html" class="myclass">LinktoFakeClass' +
'</a>>');
});
it('works correctly with type applications that include a type union', function() {
var link = helper.linkto('Array.<(linktoTest|LinktoFakeClass)>', 'link text');
expect(link).toBe('Array.&lt;(<a href="test.html">linktoTest</a>|' +
'<a href="fakeclass.html">LinktoFakeClass</a>)>');
});
});
describe("htmlsafe", function() {