Commit | Line | Data |
---|---|---|
629a09ae DV |
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 | } |