| OLD | NEW |
| 1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2014, 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 * Code for displaying the API as HTML. This is used both for generating a | 6 * Code for displaying the API as HTML. This is used both for generating a |
| 7 * full description of the API as a web page, and for generating doc comments | 7 * full description of the API as a web page, and for generating doc comments |
| 8 * in generated code. | 8 * in generated code. |
| 9 */ | 9 */ |
| 10 library to.html; | 10 library to.html; |
| 11 | 11 |
| 12 import 'dart:convert'; | 12 import 'dart:convert'; |
| 13 | 13 |
| 14 import 'package:analyzer/src/codegen/html.dart'; | 14 import 'package:analyzer/src/codegen/html.dart'; |
| 15 import 'package:analyzer/src/codegen/tools.dart'; | 15 import 'package:analyzer/src/codegen/tools.dart'; |
| 16 import 'package:front_end/src/codegen/tools.dart'; |
| 16 import 'package:html/dom.dart' as dom; | 17 import 'package:html/dom.dart' as dom; |
| 17 | 18 |
| 18 import 'api.dart'; | 19 import 'api.dart'; |
| 19 import 'from_html.dart'; | 20 import 'from_html.dart'; |
| 20 | 21 |
| 21 /** | 22 /** |
| 22 * Embedded stylesheet | 23 * Embedded stylesheet |
| 23 */ | 24 */ |
| 24 final String stylesheet = ''' | 25 final String stylesheet = ''' |
| 25 body { | 26 body { |
| (...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 133 new GeneratedFile('doc/api.html', (String pkgPath) { | 134 new GeneratedFile('doc/api.html', (String pkgPath) { |
| 134 ToHtmlVisitor visitor = new ToHtmlVisitor(readApi(pkgPath)); | 135 ToHtmlVisitor visitor = new ToHtmlVisitor(readApi(pkgPath)); |
| 135 dom.Document document = new dom.Document(); | 136 dom.Document document = new dom.Document(); |
| 136 document.append(new dom.DocumentType('html', null, null)); | 137 document.append(new dom.DocumentType('html', null, null)); |
| 137 for (dom.Node node in visitor.collectHtml(visitor.visitApi)) { | 138 for (dom.Node node in visitor.collectHtml(visitor.visitApi)) { |
| 138 document.append(node); | 139 document.append(node); |
| 139 } | 140 } |
| 140 return document.outerHtml; | 141 return document.outerHtml; |
| 141 }); | 142 }); |
| 142 | 143 |
| 144 String _toTitleCase(String str) { |
| 145 if (str.isEmpty) return str; |
| 146 return str.substring(0, 1).toUpperCase() + str.substring(1); |
| 147 } |
| 148 |
| 143 /** | 149 /** |
| 144 * Visitor that records the mapping from HTML elements to various kinds of API | 150 * Visitor that records the mapping from HTML elements to various kinds of API |
| 145 * nodes. | 151 * nodes. |
| 146 */ | 152 */ |
| 147 class ApiMappings extends HierarchicalApiVisitor { | 153 class ApiMappings extends HierarchicalApiVisitor { |
| 148 Map<dom.Element, Domain> domains = <dom.Element, Domain>{}; | 154 Map<dom.Element, Domain> domains = <dom.Element, Domain>{}; |
| 149 | 155 |
| 150 ApiMappings(Api api) : super(api); | 156 ApiMappings(Api api) : super(api); |
| 151 | 157 |
| 152 @override | 158 @override |
| (...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 262 generateNotificationsIndex(domain.notifications); | 268 generateNotificationsIndex(domain.notifications); |
| 263 } | 269 } |
| 264 }); | 270 }); |
| 265 } else if (domain.notifications.length > 0) { | 271 } else if (domain.notifications.length > 0) { |
| 266 element('div', {'class': 'subindex'}, () { | 272 element('div', {'class': 'subindex'}, () { |
| 267 generateNotificationsIndex(domain.notifications); | 273 generateNotificationsIndex(domain.notifications); |
| 268 }); | 274 }); |
| 269 } | 275 } |
| 270 } | 276 } |
| 271 | 277 |
| 272 void generateTableOfContents() { | |
| 273 ul(() { | |
| 274 writeln(); | |
| 275 | |
| 276 for (var domain in api.domains.where((domain) => !domain.experimental)) { | |
| 277 write(' '); | |
| 278 li(() { | |
| 279 link('domain_${domain.name}', () { | |
| 280 write(_toTitleCase(domain.name)); | |
| 281 }); | |
| 282 }); | |
| 283 writeln(); | |
| 284 } | |
| 285 }); | |
| 286 } | |
| 287 | |
| 288 void generateIndex() { | 278 void generateIndex() { |
| 289 h3(() => write('Domains')); | 279 h3(() => write('Domains')); |
| 290 for (var domain in api.domains) { | 280 for (var domain in api.domains) { |
| 291 if (domain.experimental || | 281 if (domain.experimental || |
| 292 (domain.requests.length == 0 && domain.notifications == 0)) { | 282 (domain.requests.length == 0 && domain.notifications == 0)) { |
| 293 continue; | 283 continue; |
| 294 } | 284 } |
| 295 generateDomainIndex(domain); | 285 generateDomainIndex(domain); |
| 296 } | 286 } |
| 297 | 287 |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 341 for (var request in requests) { | 331 for (var request in requests) { |
| 342 element( | 332 element( |
| 343 'li', | 333 'li', |
| 344 {}, | 334 {}, |
| 345 () => link( | 335 () => link( |
| 346 'request_${request.longMethod}', () => write(request.method))); | 336 'request_${request.longMethod}', () => write(request.method))); |
| 347 } | 337 } |
| 348 }); | 338 }); |
| 349 } | 339 } |
| 350 | 340 |
| 341 void generateTableOfContents() { |
| 342 ul(() { |
| 343 writeln(); |
| 344 |
| 345 for (var domain in api.domains.where((domain) => !domain.experimental)) { |
| 346 write(' '); |
| 347 li(() { |
| 348 link('domain_${domain.name}', () { |
| 349 write(_toTitleCase(domain.name)); |
| 350 }); |
| 351 }); |
| 352 writeln(); |
| 353 } |
| 354 }); |
| 355 } |
| 356 |
| 351 void generateTypesIndex(Set<String> types) { | 357 void generateTypesIndex(Set<String> types) { |
| 352 h3(() { | 358 h3(() { |
| 353 write("Types"); | 359 write("Types"); |
| 354 write(' ('); | 360 write(' ('); |
| 355 link('types', () => write('\u2191')); | 361 link('types', () => write('\u2191')); |
| 356 write(')'); | 362 write(')'); |
| 357 }); | 363 }); |
| 358 element('div', {'class': 'subindex'}, () { | 364 element('div', {'class': 'subindex'}, () { |
| 359 element('ul', {}, () { | 365 element('ul', {}, () { |
| 360 for (var type in types) { | 366 for (var type in types) { |
| (...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 416 } | 422 } |
| 417 switch (node.localName) { | 423 switch (node.localName) { |
| 418 case 'domain': | 424 case 'domain': |
| 419 visitDomain(apiMappings.domains[node]); | 425 visitDomain(apiMappings.domains[node]); |
| 420 break; | 426 break; |
| 421 case 'head': | 427 case 'head': |
| 422 head(() { | 428 head(() { |
| 423 translateHtml(node, squashParagraphs: squashParagraphs); | 429 translateHtml(node, squashParagraphs: squashParagraphs); |
| 424 element('link', { | 430 element('link', { |
| 425 'rel': 'stylesheet', | 431 'rel': 'stylesheet', |
| 426 'href': 'https://fonts.googleapis.com/css?family=Source+Code+Pro
|Roboto:500,400italic,300,400', | 432 'href': |
| 433 'https://fonts.googleapis.com/css?family=Source+Code+Pro|Rob
oto:500,400italic,300,400', |
| 427 'type': 'text/css' | 434 'type': 'text/css' |
| 428 }); | 435 }); |
| 429 element('style', {}, () { | 436 element('style', {}, () { |
| 430 writeln(stylesheet); | 437 writeln(stylesheet); |
| 431 }); | 438 }); |
| 432 }); | 439 }); |
| 433 break; | 440 break; |
| 434 case 'refactorings': | 441 case 'refactorings': |
| 435 visitRefactorings(api.refactorings); | 442 visitRefactorings(api.refactorings); |
| 436 break; | 443 break; |
| 437 case 'types': | 444 case 'types': |
| 438 visitTypes(api.types); | 445 visitTypes(api.types); |
| (...skipping 341 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 780 bool verticalBarNeeded = false; | 787 bool verticalBarNeeded = false; |
| 781 for (TypeDecl choice in typeUnion.choices) { | 788 for (TypeDecl choice in typeUnion.choices) { |
| 782 if (verticalBarNeeded) { | 789 if (verticalBarNeeded) { |
| 783 write(' | '); | 790 write(' | '); |
| 784 } | 791 } |
| 785 visitTypeDecl(choice); | 792 visitTypeDecl(choice); |
| 786 verticalBarNeeded = true; | 793 verticalBarNeeded = true; |
| 787 } | 794 } |
| 788 } | 795 } |
| 789 } | 796 } |
| 790 | |
| 791 String _toTitleCase(String str) { | |
| 792 if (str.isEmpty) return str; | |
| 793 return str.substring(0, 1).toUpperCase() + str.substring(1); | |
| 794 } | |
| OLD | NEW |