| OLD | NEW |
| 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file |
| 2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
| 3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
| 4 | 4 |
| 5 /** | 5 /** |
| 6 * This generates the reference documentation for the core libraries that come | 6 * This generates the reference documentation for the core libraries that come |
| 7 * with dart. It is built on top of dartdoc, which is a general-purpose library | 7 * with dart. It is built on top of dartdoc, which is a general-purpose library |
| 8 * for generating docs from any Dart code. This library extends that to include | 8 * for generating docs from any Dart code. This library extends that to include |
| 9 * additional information and styling specific to our standard library. | 9 * additional information and styling specific to our standard library. |
| 10 * | 10 * |
| 11 * Usage: | 11 * Usage: |
| 12 * | 12 * |
| 13 * $ dart apidoc.dart [--out=<output directory>] | 13 * $ dart apidoc.dart [--out=<output directory>] |
| 14 */ | 14 */ |
| 15 library apidoc; | 15 library apidoc; |
| 16 | 16 |
| 17 import 'dart:async'; | 17 import 'dart:async'; |
| 18 import 'dart:io'; | 18 import 'dart:io'; |
| 19 import 'dart:json' as json; | 19 import 'dart:json' as json; |
| 20 |
| 20 import 'html_diff.dart'; | 21 import 'html_diff.dart'; |
| 22 |
| 21 // TODO(rnystrom): Use "package:" URL (#4968). | 23 // TODO(rnystrom): Use "package:" URL (#4968). |
| 22 import '../../sdk/lib/_internal/compiler/implementation/mirrors/mirrors.dart'; | 24 import '../../sdk/lib/_internal/compiler/implementation/mirrors/mirrors.dart'; |
| 23 import '../../sdk/lib/_internal/compiler/implementation/mirrors/mirrors_util.dar
t'; | 25 import '../../sdk/lib/_internal/compiler/implementation/mirrors/mirrors_util.dar
t'; |
| 24 import '../../sdk/lib/_internal/dartdoc/lib/dartdoc.dart' as doc; | 26 import '../../sdk/lib/_internal/dartdoc/lib/dartdoc.dart'; |
| 25 import '../../sdk/lib/_internal/libraries.dart'; | 27 import '../../sdk/lib/_internal/libraries.dart'; |
| 26 | 28 |
| 27 HtmlDiff _diff; | 29 HtmlDiff _diff; |
| 28 | 30 |
| 29 void main() { | 31 void main() { |
| 30 final args = new Options().arguments; | 32 final args = new Options().arguments; |
| 31 | 33 |
| 32 int mode = doc.MODE_STATIC; | 34 int mode = MODE_STATIC; |
| 33 Path outputDir = new Path('docs'); | 35 Path outputDir = new Path('docs'); |
| 34 bool generateAppCache = false; | 36 bool generateAppCache = false; |
| 35 | 37 |
| 36 List<String> excludedLibraries = <String>[]; | 38 List<String> excludedLibraries = <String>[]; |
| 37 List<String> includedLibraries = <String>[]; | 39 List<String> includedLibraries = <String>[]; |
| 38 Path pkgPath; | 40 Path pkgPath; |
| 39 String version; | 41 String version; |
| 40 | 42 |
| 41 // Parse the command-line arguments. | 43 // Parse the command-line arguments. |
| 42 for (int i = 0; i < args.length; i++) { | 44 for (int i = 0; i < args.length; i++) { |
| 43 final arg = args[i]; | 45 final arg = args[i]; |
| 44 | 46 |
| 45 switch (arg) { | 47 switch (arg) { |
| 46 case '--mode=static': | 48 case '--mode=static': |
| 47 mode = doc.MODE_STATIC; | 49 mode = MODE_STATIC; |
| 48 break; | 50 break; |
| 49 | 51 |
| 50 case '--mode=live-nav': | 52 case '--mode=live-nav': |
| 51 mode = doc.MODE_LIVE_NAV; | 53 mode = MODE_LIVE_NAV; |
| 52 break; | 54 break; |
| 53 | 55 |
| 54 case '--generate-app-cache=true': | 56 case '--generate-app-cache=true': |
| 55 generateAppCache = true; | 57 generateAppCache = true; |
| 56 break; | 58 break; |
| 57 | 59 |
| 58 default: | 60 default: |
| 59 if (arg.startsWith('--exclude-lib=')) { | 61 if (arg.startsWith('--exclude-lib=')) { |
| 60 excludedLibraries.add(arg.substring('--exclude-lib='.length)); | 62 excludedLibraries.add(arg.substring('--exclude-lib='.length)); |
| 61 } else if (arg.startsWith('--include-lib=')) { | 63 } else if (arg.startsWith('--include-lib=')) { |
| 62 includedLibraries.add(arg.substring('--include-lib='.length)); | 64 includedLibraries.add(arg.substring('--include-lib='.length)); |
| 63 } else if (arg.startsWith('--out=')) { | 65 } else if (arg.startsWith('--out=')) { |
| 64 outputDir = new Path(arg.substring('--out='.length)); | 66 outputDir = new Path(arg.substring('--out='.length)); |
| 65 } else if (arg.startsWith('--pkg=')) { | 67 } else if (arg.startsWith('--pkg=')) { |
| 66 pkgPath = new Path(arg.substring('--pkg='.length)); | 68 pkgPath = new Path(arg.substring('--pkg='.length)); |
| 67 } else if (arg.startsWith('--version=')) { | 69 } else if (arg.startsWith('--version=')) { |
| 68 version = arg.substring('--version='.length); | 70 version = arg.substring('--version='.length); |
| 69 } else { | 71 } else { |
| 70 print('Unknown option: $arg'); | 72 print('Unknown option: $arg'); |
| 71 return; | 73 return; |
| 72 } | 74 } |
| 73 break; | 75 break; |
| 74 } | 76 } |
| 75 } | 77 } |
| 76 | 78 |
| 77 final libPath = doc.scriptDir.append('../../sdk/'); | 79 final libPath = scriptDir.append('../../sdk/'); |
| 78 | 80 |
| 79 doc.cleanOutputDirectory(outputDir); | 81 cleanOutputDirectory(outputDir); |
| 80 | 82 |
| 83 print('Copying static files...'); |
| 81 // The basic dartdoc-provided static content. | 84 // The basic dartdoc-provided static content. |
| 82 final copiedStatic = doc.copyDirectory( | 85 final copiedStatic = copyDirectory( |
| 83 doc.scriptDir.append('../../sdk/lib/_internal/dartdoc/static'), | 86 scriptDir.append('../../sdk/lib/_internal/dartdoc/static'), |
| 84 outputDir); | 87 outputDir); |
| 85 | 88 |
| 86 // The apidoc-specific static content. | 89 // The apidoc-specific static content. |
| 87 final copiedApiDocStatic = doc.copyDirectory( | 90 final copiedApiDocStatic = copyDirectory( |
| 88 doc.scriptDir.append('static'), | 91 scriptDir.append('static'), |
| 89 outputDir); | 92 outputDir); |
| 90 | 93 |
| 91 print('Parsing MDN data...'); | 94 print('Parsing MDN data...'); |
| 92 final mdnFile = new File.fromPath(doc.scriptDir.append('mdn/database.json')); | 95 final mdnFile = new File.fromPath(scriptDir.append('mdn/database.json')); |
| 93 final mdn = json.parse(mdnFile.readAsStringSync()); | 96 final mdn = json.parse(mdnFile.readAsStringSync()); |
| 94 | 97 |
| 95 print('Cross-referencing dart:html...'); | 98 print('Cross-referencing dart:html...'); |
| 99 // TODO(amouravski): move HtmlDiff inside of the future chain below to re-use |
| 100 // the MirrorSystem already analyzed. |
| 96 _diff = new HtmlDiff(printWarnings:false); | 101 _diff = new HtmlDiff(printWarnings:false); |
| 97 Future htmlDiff = _diff.run(libPath); | 102 Future htmlDiff = _diff.run(libPath); |
| 98 | 103 |
| 99 // Process libraries. | |
| 100 | |
| 101 // TODO(johnniwinther): Libraries for the compilation seem to be more like | 104 // TODO(johnniwinther): Libraries for the compilation seem to be more like |
| 102 // URIs. Perhaps Path should have a toURI() method. | 105 // URIs. Perhaps Path should have a toURI() method. |
| 103 // Add all of the core libraries. | 106 // Add all of the core libraries. |
| 104 final apidocLibraries = <Path>[]; | 107 final apidocLibraries = <Path>[]; |
| 105 LIBRARIES.forEach((String name, LibraryInfo info) { | 108 LIBRARIES.forEach((String name, LibraryInfo info) { |
| 106 if (info.documented) { | 109 if (info.documented) { |
| 107 apidocLibraries.add(new Path('dart:$name')); | 110 apidocLibraries.add(new Path('dart:$name')); |
| 108 } | 111 } |
| 109 }); | 112 }); |
| 110 | 113 |
| 111 var lister = new Directory.fromPath(doc.scriptDir.append('../../pkg')).list(); | 114 // TODO(amouravski): This code is really wonky. |
| 112 lister.listen( | 115 var lister = new Directory.fromPath(scriptDir.append('../../pkg')).list(); |
| 113 (entity) { | 116 lister.listen((entity) { |
| 114 if (entity is Directory) { | 117 if (entity is Directory) { |
| 115 var path = new Path(entity.path); | 118 var path = new Path(entity.path); |
| 116 var libName = path.filename; | 119 var libName = path.filename; |
| 120 var libPath = path.append('lib/$libName.dart'); |
| 117 | 121 |
| 118 // Ignore hidden directories (like .svn) as well as pkg.xcodeproj. | 122 // Ignore some libraries. |
| 119 if (libName.startsWith('.') || libName.endsWith('.xcodeproj')) { | 123 if (excludedLibraries.contains(libName)) { |
| 120 return; | 124 return; |
| 121 } | 125 } |
| 122 | 126 |
| 123 // TODO(rnystrom): Get rid of oldStylePath support when all | 127 // Ignore hidden directories (like .svn) as well as pkg.xcodeproj. |
| 124 // packages are using new layout. See #5106. | 128 if (libName.startsWith('.') || libName.endsWith('.xcodeproj')) { |
| 125 var oldStylePath = path.append('${libName}.dart'); | 129 return; |
| 126 var newStylePath = path.append('lib/${libName}.dart'); | 130 } |
| 127 | 131 |
| 128 if (new File.fromPath(oldStylePath).existsSync()) { | 132 if (new File.fromPath(libPath).existsSync()) { |
| 129 apidocLibraries.add(oldStylePath); | 133 apidocLibraries.add(libPath); |
| 130 includedLibraries.add(libName); | 134 includedLibraries.add(libName); |
| 131 } else if (new File.fromPath(newStylePath).existsSync()) { | 135 } else { |
| 132 apidocLibraries.add(newStylePath); | 136 print('Warning: could not find package at $path'); |
| 133 includedLibraries.add(libName); | 137 } |
| 134 } else { | 138 } |
| 135 print('Warning: could not find package at $path'); | 139 }, onDone: () { |
| 136 } | 140 final apidoc = new Apidoc(mdn, outputDir, mode, generateAppCache, |
| 137 } | 141 excludedLibraries, version); |
| 138 }, | 142 apidoc.dartdocPath = |
| 139 onDone: () { | 143 scriptDir.append('../../sdk/lib/_internal/dartdoc/'); |
| 140 print('Generating docs...'); | 144 // Select the libraries to include in the produced documentation: |
| 141 final apidoc = new Apidoc(mdn, outputDir, mode, generateAppCache, | 145 apidoc.includeApi = true; |
| 142 excludedLibraries, version); | 146 apidoc.includedLibraries = includedLibraries; |
| 143 apidoc.dartdocPath = | |
| 144 doc.scriptDir.append('../../sdk/lib/_internal/dartdoc/'); | |
| 145 // Select the libraries to include in the produced documentation: | |
| 146 apidoc.includeApi = true; | |
| 147 apidoc.includedLibraries = includedLibraries; | |
| 148 | 147 |
| 149 Future.wait([copiedStatic, copiedApiDocStatic, htmlDiff]).then((_) { | 148 // TODO(amouravski): make apidoc use roughly the same flow as bin/dartdoc. |
| 150 Future<bool> documented = | 149 Future.wait([copiedStatic, copiedApiDocStatic, htmlDiff]) |
| 151 apidoc.documentLibraries(apidocLibraries, libPath, pkgPath); | 150 .then((_) => apidoc.documentLibraries(apidocLibraries, libPath, pkgPath)) |
| 152 | 151 .then((_) => compileScript(mode, outputDir, libPath)) |
| 153 documented.then((_) { | 152 .then((_) => print(apidoc.status)) |
| 154 final compiled = doc.compileScript(mode, outputDir, libPath); | 153 .catchError((e) => print('Error: generation failed: ${e.error}')) |
| 155 | 154 .whenComplete(() => apidoc.cleanup()); |
| 156 Future.wait([compiled]).then((_) { | 155 }); |
| 157 apidoc.cleanup(); | |
| 158 }); | |
| 159 }, onError: (AsyncError asyncError) { | |
| 160 print('Generation failed: ${asyncError.error}'); | |
| 161 apidoc.cleanup(); | |
| 162 }); | |
| 163 }); | |
| 164 }); | |
| 165 } | 156 } |
| 166 | 157 |
| 167 class Apidoc extends doc.Dartdoc { | 158 class Apidoc extends Dartdoc { |
| 168 /** Big ball of JSON containing the scraped MDN documentation. */ | 159 /** Big ball of JSON containing the scraped MDN documentation. */ |
| 169 final Map mdn; | 160 final Map mdn; |
| 170 | 161 |
| 171 | 162 |
| 172 // A set of type names (TypeMirror.simpleName values) to ignore while | 163 // A set of type names (TypeMirror.simpleName values) to ignore while |
| 173 // looking up information from MDN data. TODO(eub, jacobr): fix up the MDN | 164 // looking up information from MDN data. TODO(eub, jacobr): fix up the MDN |
| 174 // import scripts so they run correctly and generate data that doesn't have | 165 // import scripts so they run correctly and generate data that doesn't have |
| 175 // any entries that need to be ignored. | 166 // any entries that need to be ignored. |
| 176 static Set<String> _mdnTypeNamesToSkip = null; | 167 static Set<String> _mdnTypeNamesToSkip = null; |
| 177 | 168 |
| (...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 247 var s = document.getElementsByTagName("script")[0]; | 238 var s = document.getElementsByTagName("script")[0]; |
| 248 s.parentNode.insertBefore(ga, s); | 239 s.parentNode.insertBefore(ga, s); |
| 249 })(); | 240 })(); |
| 250 </script> | 241 </script> |
| 251 '''); | 242 '''); |
| 252 } | 243 } |
| 253 | 244 |
| 254 void docIndexLibrary(LibraryMirror library) { | 245 void docIndexLibrary(LibraryMirror library) { |
| 255 // TODO(rnystrom): Hackish. The IO libraries reference this but we don't | 246 // TODO(rnystrom): Hackish. The IO libraries reference this but we don't |
| 256 // want it in the docs. | 247 // want it in the docs. |
| 257 if (doc.displayName(library) == 'dart:nativewrappers') return; | 248 if (displayName(library) == 'dart:nativewrappers') return; |
| 258 super.docIndexLibrary(library); | 249 super.docIndexLibrary(library); |
| 259 } | 250 } |
| 260 | 251 |
| 261 void docLibraryNavigationJson(LibraryMirror library, List libraryList) { | 252 void docLibraryNavigationJson(LibraryMirror library, List libraryList) { |
| 262 // TODO(rnystrom): Hackish. The IO libraries reference this but we don't | 253 // TODO(rnystrom): Hackish. The IO libraries reference this but we don't |
| 263 // want it in the docs. | 254 // want it in the docs. |
| 264 if (doc.displayName(library) == 'dart:nativewrappers') return; | 255 if (displayName(library) == 'dart:nativewrappers') return; |
| 265 super.docLibraryNavigationJson(library, libraryList); | 256 super.docLibraryNavigationJson(library, libraryList); |
| 266 } | 257 } |
| 267 | 258 |
| 268 void docLibrary(LibraryMirror library) { | 259 void docLibrary(LibraryMirror library) { |
| 269 // TODO(rnystrom): Hackish. The IO libraries reference this but we don't | 260 // TODO(rnystrom): Hackish. The IO libraries reference this but we don't |
| 270 // want it in the docs. | 261 // want it in the docs. |
| 271 if (doc.displayName(library) == 'dart:nativewrappers') return; | 262 if (displayName(library) == 'dart:nativewrappers') return; |
| 272 super.docLibrary(library); | 263 super.docLibrary(library); |
| 273 } | 264 } |
| 274 | 265 |
| 275 doc.DocComment getLibraryComment(LibraryMirror library) { | 266 DocComment getLibraryComment(LibraryMirror library) { |
| 276 return super.getLibraryComment(library); | 267 return super.getLibraryComment(library); |
| 277 } | 268 } |
| 278 | 269 |
| 279 doc.DocComment getTypeComment(TypeMirror type) { | 270 DocComment getTypeComment(TypeMirror type) { |
| 280 return _mergeDocs( | 271 return _mergeDocs( |
| 281 includeMdnTypeComment(type), super.getTypeComment(type)); | 272 includeMdnTypeComment(type), super.getTypeComment(type)); |
| 282 } | 273 } |
| 283 | 274 |
| 284 doc.DocComment getMemberComment(MemberMirror member) { | 275 DocComment getMemberComment(MemberMirror member) { |
| 285 return _mergeDocs( | 276 return _mergeDocs( |
| 286 includeMdnMemberComment(member), super.getMemberComment(member)); | 277 includeMdnMemberComment(member), super.getMemberComment(member)); |
| 287 } | 278 } |
| 288 | 279 |
| 289 doc.DocComment _mergeDocs(doc.MdnComment mdnComment, | 280 DocComment _mergeDocs(MdnComment mdnComment, |
| 290 doc.DocComment fileComment) { | 281 DocComment fileComment) { |
| 291 // Otherwise, prefer comment from the (possibly generated) Dart file. | 282 // Otherwise, prefer comment from the (possibly generated) Dart file. |
| 292 if (fileComment != null) return fileComment; | 283 if (fileComment != null) return fileComment; |
| 293 | 284 |
| 294 // Finally, fallback on MDN if available. | 285 // Finally, fallback on MDN if available. |
| 295 if (mdnComment != null) { | 286 if (mdnComment != null) { |
| 296 mdnUrl = mdnComment.mdnUrl; | 287 mdnUrl = mdnComment.mdnUrl; |
| 297 return mdnComment; | 288 return mdnComment; |
| 298 } | 289 } |
| 299 | 290 |
| 300 // We got nothing! | 291 // We got nothing! |
| (...skipping 25 matching lines...) Expand all Loading... |
| 326 <a href="$CCA">Creative Commons: Attribution-Sharealike license</a>. | 317 <a href="$CCA">Creative Commons: Attribution-Sharealike license</a>. |
| 327 Mozilla has no other association with Dart or dartlang.org. We | 318 Mozilla has no other association with Dart or dartlang.org. We |
| 328 encourage you to improve the web by | 319 encourage you to improve the web by |
| 329 <a href="$CONTRIB">contributing</a> to | 320 <a href="$CONTRIB">contributing</a> to |
| 330 <a href="$MDN">The Mozilla Developer Network</a>. | 321 <a href="$MDN">The Mozilla Developer Network</a>. |
| 331 </p> | 322 </p> |
| 332 '''); | 323 '''); |
| 333 } | 324 } |
| 334 } | 325 } |
| 335 | 326 |
| 336 doc.MdnComment lookupMdnComment(Mirror mirror) { | 327 MdnComment lookupMdnComment(Mirror mirror) { |
| 337 if (mirror is TypeMirror) { | 328 if (mirror is TypeMirror) { |
| 338 return includeMdnTypeComment(mirror); | 329 return includeMdnTypeComment(mirror); |
| 339 } else if (mirror is MemberMirror) { | 330 } else if (mirror is MemberMirror) { |
| 340 return includeMdnMemberComment(mirror); | 331 return includeMdnMemberComment(mirror); |
| 341 } else { | 332 } else { |
| 342 return null; | 333 return null; |
| 343 } | 334 } |
| 344 } | 335 } |
| 345 | 336 |
| 346 /** | 337 /** |
| 347 * Gets the MDN-scraped docs for [type], or `null` if this type isn't | 338 * Gets the MDN-scraped docs for [type], or `null` if this type isn't |
| 348 * scraped from MDN. | 339 * scraped from MDN. |
| 349 */ | 340 */ |
| 350 doc.MdnComment includeMdnTypeComment(TypeMirror type) { | 341 MdnComment includeMdnTypeComment(TypeMirror type) { |
| 351 if (_mdnTypeNamesToSkip.contains(type.simpleName)) { | 342 if (_mdnTypeNamesToSkip.contains(type.simpleName)) { |
| 352 print('Skipping MDN type ${type.simpleName}'); | |
| 353 return null; | 343 return null; |
| 354 } | 344 } |
| 355 | 345 |
| 356 var typeString = ''; | 346 var typeString = ''; |
| 357 if (HTML_LIBRARY_NAMES.contains(doc.displayName(type.library))) { | 347 if (HTML_LIBRARY_NAMES.contains(displayName(type.library))) { |
| 358 // If it's an HTML type, try to map it to a base DOM type so we can find | 348 // If it's an HTML type, try to map it to a base DOM type so we can find |
| 359 // the MDN docs. | 349 // the MDN docs. |
| 360 final domTypes = _diff.htmlTypesToDom[type.qualifiedName]; | 350 final domTypes = _diff.htmlTypesToDom[type.qualifiedName]; |
| 361 | 351 |
| 362 // Couldn't find a DOM type. | 352 // Couldn't find a DOM type. |
| 363 if ((domTypes == null) || (domTypes.length != 1)) return null; | 353 if ((domTypes == null) || (domTypes.length != 1)) return null; |
| 364 | 354 |
| 365 // Use the corresponding DOM type when searching MDN. | 355 // Use the corresponding DOM type when searching MDN. |
| 366 // TODO(rnystrom): Shame there isn't a simpler way to get the one item | 356 // TODO(rnystrom): Shame there isn't a simpler way to get the one item |
| 367 // out of a singleton Set. | 357 // out of a singleton Set. |
| 368 // TODO(floitsch): switch to domTypes.first, once that's implemented. | 358 // TODO(floitsch): switch to domTypes.first, once that's implemented. |
| 369 var iter = domTypes.iterator; | 359 var iter = domTypes.iterator; |
| 370 iter.moveNext(); | 360 iter.moveNext(); |
| 371 typeString = iter.current; | 361 typeString = iter.current; |
| 372 } else { | 362 } else { |
| 373 // Not a DOM type. | 363 // Not a DOM type. |
| 374 return null; | 364 return null; |
| 375 } | 365 } |
| 376 | 366 |
| 377 final mdnType = mdn[typeString]; | 367 final mdnType = mdn[typeString]; |
| 378 if (mdnType == null) return null; | 368 if (mdnType == null) return null; |
| 379 if (mdnType['skipped'] != null) return null; | 369 if (mdnType['skipped'] != null) return null; |
| 380 if (mdnType['summary'] == null) return null; | 370 if (mdnType['summary'] == null) return null; |
| 381 if (mdnType['summary'].trim().isEmpty) return null; | 371 if (mdnType['summary'].trim().isEmpty) return null; |
| 382 | 372 |
| 383 // Remember which MDN page we're using so we can attribute it. | 373 // Remember which MDN page we're using so we can attribute it. |
| 384 return new doc.MdnComment(mdnType['summary'], mdnType['srcUrl']); | 374 return new MdnComment(mdnType['summary'], mdnType['srcUrl']); |
| 385 } | 375 } |
| 386 | 376 |
| 387 /** | 377 /** |
| 388 * Gets the MDN-scraped docs for [member], or `null` if this type isn't | 378 * Gets the MDN-scraped docs for [member], or `null` if this type isn't |
| 389 * scraped from MDN. | 379 * scraped from MDN. |
| 390 */ | 380 */ |
| 391 doc.MdnComment includeMdnMemberComment(MemberMirror member) { | 381 MdnComment includeMdnMemberComment(MemberMirror member) { |
| 392 var library = findLibrary(member); | 382 var library = findLibrary(member); |
| 393 var memberString = ''; | 383 var memberString = ''; |
| 394 if (HTML_LIBRARY_NAMES.contains(doc.displayName(library))) { | 384 if (HTML_LIBRARY_NAMES.contains(displayName(library))) { |
| 395 // If it's an HTML type, try to map it to a DOM type name so we can find | 385 // If it's an HTML type, try to map it to a DOM type name so we can find |
| 396 // the MDN docs. | 386 // the MDN docs. |
| 397 final domMembers = _diff.htmlToDom[member.qualifiedName]; | 387 final domMembers = _diff.htmlToDom[member.qualifiedName]; |
| 398 | 388 |
| 399 // Couldn't find a DOM type. | 389 // Couldn't find a DOM type. |
| 400 if ((domMembers == null) || (domMembers.length != 1)) return null; | 390 if ((domMembers == null) || (domMembers.length != 1)) return null; |
| 401 | 391 |
| 402 // Use the corresponding DOM member when searching MDN. | 392 // Use the corresponding DOM member when searching MDN. |
| 403 // TODO(rnystrom): Shame there isn't a simpler way to get the one item | 393 // TODO(rnystrom): Shame there isn't a simpler way to get the one item |
| 404 // out of a singleton Set. | 394 // out of a singleton Set. |
| (...skipping 22 matching lines...) Expand all Loading... |
| 427 break; | 417 break; |
| 428 } | 418 } |
| 429 } | 419 } |
| 430 } | 420 } |
| 431 | 421 |
| 432 if (mdnMember == null) return null; | 422 if (mdnMember == null) return null; |
| 433 if (mdnMember['help'] == null) return null; | 423 if (mdnMember['help'] == null) return null; |
| 434 if (mdnMember['help'].trim().isEmpty) return null; | 424 if (mdnMember['help'].trim().isEmpty) return null; |
| 435 | 425 |
| 436 // Remember which MDN page we're using so we can attribute it. | 426 // Remember which MDN page we're using so we can attribute it. |
| 437 return new doc.MdnComment(mdnMember['help'], mdnType['srcUrl']); | 427 return new MdnComment(mdnMember['help'], mdnType['srcUrl']); |
| 438 } | 428 } |
| 439 | 429 |
| 440 /** | 430 /** |
| 441 * Returns a link to [member], relative to a type page that may be in a | 431 * Returns a link to [member], relative to a type page that may be in a |
| 442 * different library than [member]. | 432 * different library than [member]. |
| 443 */ | 433 */ |
| 444 String _linkMember(MemberMirror member) { | 434 String _linkMember(MemberMirror member) { |
| 445 final typeName = member.owner.simpleName; | 435 final typeName = member.owner.simpleName; |
| 446 var memberName = '$typeName.${member.simpleName}'; | 436 var memberName = '$typeName.${member.simpleName}'; |
| 447 if (member is MethodMirror && (member.isConstructor || member.isFactory)) { | 437 if (member is MethodMirror && (member.isConstructor || member.isFactory)) { |
| 448 final separator = member.constructorName == '' ? '' : '.'; | 438 final separator = member.constructorName == '' ? '' : '.'; |
| 449 memberName = 'new $typeName$separator${member.constructorName}'; | 439 memberName = 'new $typeName$separator${member.constructorName}'; |
| 450 } | 440 } |
| 451 | 441 |
| 452 return a(memberUrl(member), memberName); | 442 return a(memberUrl(member), memberName); |
| 453 } | 443 } |
| 454 } | 444 } |
| OLD | NEW |