1 /** Handle the creation of HTML links to documented symbols. |
|
2 @constructor |
|
3 */ |
|
4 function Link() { |
|
5 this.alias = ""; |
|
6 this.src = ""; |
|
7 this.file = ""; |
|
8 this.text = ""; |
|
9 this.innerName = ""; |
|
10 this.classLink = false; |
|
11 this.targetName = ""; |
|
12 |
|
13 this.target = function(targetName) { |
|
14 if (defined(targetName)) this.targetName = targetName; |
|
15 return this; |
|
16 } |
|
17 this.inner = function(inner) { |
|
18 if (defined(inner)) this.innerName = inner; |
|
19 return this; |
|
20 } |
|
21 this.withText = function(text) { |
|
22 if (defined(text)) this.text = text; |
|
23 return this; |
|
24 } |
|
25 this.toSrc = function(filename) { |
|
26 if (defined(filename)) this.src = filename; |
|
27 return this; |
|
28 } |
|
29 this.toSymbol = function(alias) { |
|
30 if (defined(alias)) this.alias = new String(alias); |
|
31 return this; |
|
32 } |
|
33 this.toClass = function(alias) { |
|
34 this.classLink = true; |
|
35 return this.toSymbol(alias); |
|
36 } |
|
37 this.toFile = function(file) { |
|
38 if (defined(file)) this.file = file; |
|
39 return this; |
|
40 } |
|
41 |
|
42 this.toString = function() { |
|
43 var linkString; |
|
44 var thisLink = this; |
|
45 |
|
46 if (this.alias) { |
|
47 linkString = this.alias.replace(/(^|[^a-z$0-9_#.:^-])([|a-z$0-9_#.:^-]+)($|[^a-z$0-9_#.:^-])/i, |
|
48 function(match, prematch, symbolName, postmatch) { |
|
49 var symbolNames = symbolName.split("|"); |
|
50 var links = []; |
|
51 for (var i = 0, l = symbolNames.length; i < l; i++) { |
|
52 thisLink.alias = symbolNames[i]; |
|
53 links.push(thisLink._makeSymbolLink(symbolNames[i])); |
|
54 } |
|
55 return prematch+links.join("|")+postmatch; |
|
56 } |
|
57 ); |
|
58 } |
|
59 else if (this.src) { |
|
60 linkString = thisLink._makeSrcLink(this.src); |
|
61 } |
|
62 else if (this.file) { |
|
63 linkString = thisLink._makeFileLink(this.file); |
|
64 } |
|
65 |
|
66 return linkString; |
|
67 } |
|
68 } |
|
69 |
|
70 /** prefixed for hashes */ |
|
71 Link.hashPrefix = ""; |
|
72 |
|
73 /** Appended to the front of relative link paths. */ |
|
74 Link.base = ""; |
|
75 |
|
76 Link.symbolNameToLinkName = function(symbol) { |
|
77 var linker = "", |
|
78 ns = ""; |
|
79 |
|
80 if (symbol.isStatic) linker = "."; |
|
81 else if (symbol.isInner) linker = "-"; |
|
82 |
|
83 if (symbol.isEvent && !/^event:/.test(symbol.name)) { |
|
84 ns = "event:"; |
|
85 } |
|
86 return Link.hashPrefix+linker+ns+symbol.name; |
|
87 } |
|
88 |
|
89 Link.getSymbol= function(alias) { |
|
90 var symbol= Link.symbolSet.getSymbol(alias); |
|
91 |
|
92 if (symbol) |
|
93 return symbol; |
|
94 |
|
95 if ('#'!==alias.charAt(0) || !Link.currentSymbol) |
|
96 return null; |
|
97 |
|
98 // resolve relative name |
|
99 var container= Link.currentSymbol; |
|
100 |
|
101 while (container) |
|
102 { |
|
103 symbol= Link.symbolSet.getSymbol(container.alias + alias); |
|
104 if (symbol) |
|
105 return symbol; |
|
106 |
|
107 // No superclass |
|
108 if (!container.augments.length) |
|
109 return null; |
|
110 |
|
111 container= Link.symbolSet.getSymbol(container.augments[0].desc); |
|
112 } |
|
113 |
|
114 return null; |
|
115 } |
|
116 |
|
117 /** Create a link to another symbol. */ |
|
118 Link.prototype._makeSymbolLink = function(alias) { |
|
119 var linkBase = Link.base+publish.conf.symbolsDir; |
|
120 var linkTo = Link.getSymbol(alias); |
|
121 var linkPath; |
|
122 var target = (this.targetName)? " target=\""+this.targetName+"\"" : ""; |
|
123 |
|
124 // if there is no symbol by that name just return the name unaltered |
|
125 if (!linkTo) |
|
126 return this.text || alias; |
|
127 |
|
128 // it's a symbol in another file |
|
129 else { |
|
130 if (!linkTo.is("CONSTRUCTOR") && !linkTo.isNamespace) { // it's a method or property |
|
131 linkPath= (Link.filemap) ? Link.filemap[linkTo.memberOf] : |
|
132 escape(linkTo.memberOf) || "_global_"; |
|
133 linkPath += publish.conf.ext + "#" + Link.symbolNameToLinkName(linkTo); |
|
134 } |
|
135 else { |
|
136 linkPath = (Link.filemap)? Link.filemap[linkTo.alias] : escape(linkTo.alias); |
|
137 linkPath += publish.conf.ext;// + (this.classLink? "":"#" + Link.hashPrefix + "constructor"); |
|
138 } |
|
139 linkPath = linkBase + linkPath |
|
140 } |
|
141 |
|
142 var linkText= this.text || alias; |
|
143 |
|
144 var link = {linkPath: linkPath, linkText: linkText, linkInner: (this.innerName? "#"+this.innerName : "")}; |
|
145 |
|
146 if (typeof JSDOC.PluginManager != "undefined") { |
|
147 JSDOC.PluginManager.run("onSymbolLink", link); |
|
148 } |
|
149 |
|
150 return "<a href=\""+link.linkPath+link.linkInner+"\""+target+">"+link.linkText+"</a>"; |
|
151 } |
|
152 |
|
153 /** Create a link to a source file. */ |
|
154 Link.prototype._makeSrcLink = function(srcFilePath) { |
|
155 var target = (this.targetName)? " target=\""+this.targetName+"\"" : ""; |
|
156 |
|
157 // transform filepath into a filename |
|
158 var srcFile = srcFilePath.replace(/\.\.?[\\\/]/g, "").replace(/[:\\\/]/g, "_"); |
|
159 var outFilePath = Link.base + publish.conf.srcDir + srcFile + publish.conf.ext; |
|
160 |
|
161 if (!this.text) this.text = FilePath.fileName(srcFilePath); |
|
162 return "<a href=\""+outFilePath+"\""+target+">"+this.text+"</a>"; |
|
163 } |
|
164 |
|
165 /** Create a link to a source file. */ |
|
166 Link.prototype._makeFileLink = function(filePath) { |
|
167 var target = (this.targetName)? " target=\""+this.targetName+"\"" : ""; |
|
168 |
|
169 var outFilePath = Link.base + filePath; |
|
170 |
|
171 if (!this.text) this.text = filePath; |
|
172 return "<a href=\""+outFilePath+"\""+target+">"+this.text+"</a>"; |
|
173 } |
|