1 /** 2 * @class 3 * LinkクラスはシンボルやファイルへのHTMLリンク(<a>タグ)を作成する機能を提供します。 <br> 4 * Linkオブジェクトのメソッドのほとんどは自分自身への参照を返すため、以下のようにリンクの設定処理をチェーンした後、 5 * 最終的に[[toString]]メソッドでタグ文字列を出力するのが標準的な使用方法です。 6 * <div class="example_in_desc" > 7 * new Link().toSymbol("MySymbol").withText("マイシンボル").target("_blank").toString(); 8 * </div> 9 * 上の処理は次のようなHTMLテキストを出力します。(シンボルの出力先設定は標準テンプレートと同一と仮定) 10 * <pre class="example_in_desc" > 11 * <a href="./symbols/MySymbol.html" target="_blank" >マイシンボル</a> 12 * </pre> 13 * <b>注意:</b> 14 * Linkオブジェクトを正常に動作させるには、テンプレートのpublish関数にconfプロパティが存在していなくてはなりません。 15 * <p class="org_comment"> 16 * Handle the creation of HTML links to documented symbols. 17 * </p> 18 */ 19 function Link() { 20 this.alias = ""; 21 this.src = ""; 22 this.file = ""; 23 this.text = ""; 24 this.innerName = ""; 25 this.classLink = false; 26 this.targetName = ""; 27 28 /** 29 * <a>タグのtarget属性の値を設定します。 30 * @param {String} targetName target属性値 31 * @return {Link} このオブジェクトへの参照 32 */ 33 this.target = function(targetName) { 34 if (defined(targetName)) this.targetName = targetName; 35 return this; 36 } 37 38 /** 39 * ページ内リンクのアンカー名を設定します。 40 * @param {String} inner アンカー名 41 * @return {Link} このオブジェクトへの参照 42 */ 43 this.inner = function(inner) { 44 if (defined(inner)) this.innerName = inner; 45 return this; 46 } 47 48 /** 49 * リンクテキストを設定します。 50 * この指定を行わなかった場合、状況に応じてシンボルエイリアスやファイルパスが出力されます。 51 * @param {String} text リンクテキスト 52 * @return {Link} このオブジェクトへの参照 53 */ 54 this.withText = function(text) { 55 if (defined(text)) this.text = text; 56 return this; 57 } 58 59 /** 60 * リンク先としてソースファイル名を設定します。これはハイライトされたソースコードファイルへのリンクとなります。 61 * @param {String} filename ソースファイル名 62 * @return {Link} このオブジェクトへの参照 63 */ 64 this.toSrc = function(filename) { 65 if (defined(filename)) this.src = filename; 66 return this; 67 } 68 69 /** 70 * リンク先としてシンボルのエイリアスを設定します。 71 * @param {String} alias シンボルのエイリアス 72 * @return {Link} このオブジェクトへの参照 73 */ 74 this.toSymbol = function(alias) { 75 if (defined(alias)) this.alias = new String(alias); 76 return this; 77 } 78 79 /** 80 * リンク先としてクラスシンボルのエイリアスを設定します。<br> 81 * ※現行バージョンではこのメソッドと[[toSymbol]]メソッドの動作に違いはありません。 82 * @param {String} alias クラスシンボルのエイリアス 83 * @return {Link} このオブジェクトへの参照 84 */ 85 this.toClass = function(alias) { 86 this.classLink = true; 87 return this.toSymbol(alias); 88 } 89 90 /** 91 * リンク先としてファイルパスを設定します。 92 * @param {String} file [[Link.base]]プロパティの位置を基準としたファイルの相対パス 93 * @return {Link} このオブジェクトへの参照 94 */ 95 this.toFile = function(file) { 96 if (defined(file)) this.file = file; 97 return this; 98 } 99 100 /** 101 * オブジェクトの文字列表現として、現在の設定に基づいて作成された<a>タグのHTMLテキストを返します。 102 * @return {String} <a>タグのHTMLテキスト 103 */ 104 this.toString = function() { 105 var linkString; 106 var thisLink = this; 107 108 if (this.alias) { 109 linkString = this.alias.replace(/(^|[^a-z$0-9_#.:^-])([|a-z$0-9_#.:^-]+)($|[^a-z$0-9_#.:^-])/i, 110 function(match, prematch, symbolName, postmatch) { 111 var symbolNames = symbolName.split("|"); 112 var links = []; 113 for (var i = 0, l = symbolNames.length; i < l; i++) { 114 thisLink.alias = symbolNames[i]; 115 links.push(thisLink._makeSymbolLink(symbolNames[i])); 116 } 117 return prematch+links.join("|")+postmatch; 118 } 119 ); 120 } 121 else if (this.src) { 122 linkString = thisLink._makeSrcLink(this.src); 123 } 124 else if (this.file) { 125 linkString = thisLink._makeFileLink(this.file); 126 } 127 128 return linkString; 129 } 130 } 131 132 /** 133 * [[Link.symbolNameToLinkName]]メソッドでシンボル名からページ内リンクのアンカー名を作成する際、 134 * アンカー名の先頭に付加されるプリフィックス 135 * <p class="org_comment" >prefixed for hashes</p> 136 * @type String 137 */ 138 Link.hashPrefix = ""; 139 140 /** 141 * 作成されるリンクの、ドキュメント出力ディレクトリとの相対位置を示すパス文字列("../"など) 142 * <p class="org_comment" >Appended to the front of relative link paths.</p> 143 * @type String 144 */ 145 Link.base = ""; 146 147 /** 148 * @name Link.symbolSet 149 * @desc 150 * シンボルセット。ネームパスからシンボルを取得するために使用します。 151 * Linkクラスをテンプレートから使用する場合、publish()関数が受け取った[[JSDOC.SymbolSet]]オブジェクトを 152 * 事前にこのプロパティに設定しておく必要があります。 153 * @field @type JSDOC.SymbolSet 154 */ 155 156 /** 157 * クラスシンボルから、そのシンボルを表すリンクアンカー名を作成します。 158 * @param {JSDOC.Symbol} symbol クラスシンボル 159 * @return {String} リンクアンカー名 160 */ 161 Link.symbolNameToLinkName = function(symbol) { 162 var linker = ""; 163 if (symbol.isStatic) linker = "."; 164 else if (symbol.isInner) linker = "-"; 165 166 return Link.hashPrefix+linker+symbol.name; 167 } 168 169 /** Create a link to another symbol. */ 170 Link.prototype._makeSymbolLink = function(alias) { 171 var linkBase = Link.base+publish.conf.symbolsDir; 172 var linkTo = Link.symbolSet.getSymbol(alias); 173 var linkPath; 174 var target = (this.targetName)? " target=\""+this.targetName+"\"" : ""; 175 176 // is it an internal link? 177 if (alias.charAt(0) == "#") var linkPath = alias; 178 179 // if there is no symbol by that name just return the name unaltered 180 else if (!linkTo) return this.text || alias; 181 182 // it's a symbol in another file 183 else { 184 if (!linkTo.is("CONSTRUCTOR") && !linkTo.isNamespace) { // it's a method or property 185 if (linkTo.isEvent) { 186 linkPath = 187 (Link.filemap)? Link.filemap[linkTo.memberOf] 188 : 189 escape(linkTo.memberOf) || "_global_"; 190 linkPath += publish.conf.ext + "#event:" + Link.symbolNameToLinkName(linkTo); 191 } 192 else { 193 linkPath = 194 (Link.filemap)? Link.filemap[linkTo.memberOf] 195 : 196 escape(linkTo.memberOf) || "_global_"; 197 linkPath += publish.conf.ext + "#" + Link.symbolNameToLinkName(linkTo); 198 } 199 } 200 else { 201 linkPath = (Link.filemap)? Link.filemap[linkTo.alias] : escape(linkTo.alias); 202 linkPath += publish.conf.ext;// + (this.classLink? "":"#" + Link.hashPrefix + "constructor"); 203 } 204 linkPath = linkBase + linkPath 205 } 206 207 var linkText = this.text || alias; 208 209 var link = {linkPath: linkPath, linkText: linkText, linkInner: (this.innerName? "#"+this.innerName : "")}; 210 211 if (typeof JSDOC.PluginManager != "undefined") { 212 JSDOC.PluginManager.run("onSymbolLink", link); 213 } 214 215 return "<a href=\""+link.linkPath+link.linkInner+"\""+target+">"+link.linkText+"</a>"; 216 } 217 218 /** Create a link to a source file. */ 219 Link.prototype._makeSrcLink = function(srcFilePath) { 220 var target = (this.targetName)? " target=\""+this.targetName+"\"" : ""; 221 222 // transform filepath into a filename 223 var srcFile = srcFilePath.replace(/\.\.?[\\\/]/g, "").replace(/[:\\\/]/g, "_"); 224 var outFilePath = Link.base + publish.conf.srcDir + srcFile + publish.conf.ext; 225 226 if (!this.text) this.text = FilePath.fileName(srcFilePath); 227 return "<a href=\""+outFilePath+"\""+target+">"+this.text+"</a>"; 228 } 229 230 /** Create a link to a source file. */ 231 Link.prototype._makeFileLink = function(filePath) { 232 var target = (this.targetName)? " target=\""+this.targetName+"\"" : ""; 233 234 var outFilePath = Link.base + filePath; 235 236 if (!this.text) this.text = filePath; 237 return "<a href=\""+outFilePath+"\""+target+">"+this.text+"</a>"; 238 }