| 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; | |
| 11 | |
| 12 import 'dart:convert'; | 10 import 'dart:convert'; |
| 13 | 11 |
| 14 import 'package:analyzer/src/codegen/html.dart'; | 12 import 'package:analyzer/src/codegen/html.dart'; |
| 15 import 'package:analyzer/src/codegen/tools.dart'; | 13 import 'package:analyzer/src/codegen/tools.dart'; |
| 16 import 'package:front_end/src/codegen/tools.dart'; | 14 import 'package:front_end/src/codegen/tools.dart'; |
| 17 import 'package:html/dom.dart' as dom; | 15 import 'package:html/dom.dart' as dom; |
| 18 | 16 |
| 19 import 'api.dart'; | 17 import 'api.dart'; |
| 20 import 'from_html.dart'; | 18 import 'from_html.dart'; |
| 21 | 19 |
| (...skipping 179 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 201 void i(void callback()) => element('i', {}, callback); | 199 void i(void callback()) => element('i', {}, callback); |
| 202 void li(void callback()) => element('li', {}, callback); | 200 void li(void callback()) => element('li', {}, callback); |
| 203 void link(String id, void callback(), [Map<dynamic, String> attributes]) { | 201 void link(String id, void callback(), [Map<dynamic, String> attributes]) { |
| 204 attributes ??= {}; | 202 attributes ??= {}; |
| 205 attributes['href'] = '#$id'; | 203 attributes['href'] = '#$id'; |
| 206 element('a', attributes, callback); | 204 element('a', attributes, callback); |
| 207 } | 205 } |
| 208 | 206 |
| 209 void p(void callback()) => element('p', {}, callback); | 207 void p(void callback()) => element('p', {}, callback); |
| 210 void pre(void callback()) => element('pre', {}, callback); | 208 void pre(void callback()) => element('pre', {}, callback); |
| 209 void span(String cls, void callback()) => |
| 210 element('span', {'class': cls}, callback); |
| 211 void title(void callback()) => element('title', {}, callback); | 211 void title(void callback()) => element('title', {}, callback); |
| 212 void tt(void callback()) => element('tt', {}, callback); | 212 void tt(void callback()) => element('tt', {}, callback); |
| 213 void ul(void callback()) => element('ul', {}, callback); | 213 void ul(void callback()) => element('ul', {}, callback); |
| 214 void span(String cls, void callback()) => | |
| 215 element('span', {'class': cls}, callback); | |
| 216 } | 214 } |
| 217 | 215 |
| 218 /** | 216 /** |
| 219 * Visitor that generates HTML documentation of the API. | 217 * Visitor that generates HTML documentation of the API. |
| 220 */ | 218 */ |
| 221 class ToHtmlVisitor extends HierarchicalApiVisitor | 219 class ToHtmlVisitor extends HierarchicalApiVisitor |
| 222 with HtmlMixin, HtmlGenerator { | 220 with HtmlMixin, HtmlGenerator { |
| 223 /** | 221 /** |
| 224 * Set of types defined in the API. | 222 * Set of types defined in the API. |
| 225 */ | 223 */ |
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 272 generateNotificationsIndex(domain.notifications); | 270 generateNotificationsIndex(domain.notifications); |
| 273 } | 271 } |
| 274 }); | 272 }); |
| 275 } else if (domain.notifications.length > 0) { | 273 } else if (domain.notifications.length > 0) { |
| 276 element('div', {'class': 'subindex'}, () { | 274 element('div', {'class': 'subindex'}, () { |
| 277 generateNotificationsIndex(domain.notifications); | 275 generateNotificationsIndex(domain.notifications); |
| 278 }); | 276 }); |
| 279 } | 277 } |
| 280 } | 278 } |
| 281 | 279 |
| 280 void generateDomainsHeader() { |
| 281 h1(() { |
| 282 write('Domains'); |
| 283 }); |
| 284 } |
| 285 |
| 282 void generateIndex() { | 286 void generateIndex() { |
| 283 h3(() => write('Domains')); | 287 h3(() => write('Domains')); |
| 284 for (var domain in api.domains) { | 288 for (var domain in api.domains) { |
| 285 if (domain.experimental || | 289 if (domain.experimental || |
| 286 (domain.requests.length == 0 && domain.notifications == 0)) { | 290 (domain.requests.length == 0 && domain.notifications == 0)) { |
| 287 continue; | 291 continue; |
| 288 } | 292 } |
| 289 generateDomainIndex(domain); | 293 generateDomainIndex(domain); |
| 290 } | 294 } |
| 291 | 295 |
| (...skipping 10 matching lines...) Expand all Loading... |
| 302 'li', | 306 'li', |
| 303 {}, | 307 {}, |
| 304 () => link('notification_${notification.longEvent}', | 308 () => link('notification_${notification.longEvent}', |
| 305 () => write(notification.event))); | 309 () => write(notification.event))); |
| 306 } | 310 } |
| 307 }); | 311 }); |
| 308 }); | 312 }); |
| 309 } | 313 } |
| 310 | 314 |
| 311 void generateRefactoringsIndex(Iterable<Refactoring> refactorings) { | 315 void generateRefactoringsIndex(Iterable<Refactoring> refactorings) { |
| 316 if (refactorings == null) { |
| 317 return; |
| 318 } |
| 312 h3(() { | 319 h3(() { |
| 313 write("Refactorings"); | 320 write("Refactorings"); |
| 314 write(' ('); | 321 write(' ('); |
| 315 link('refactorings', () => write('\u2191')); | 322 link('refactorings', () => write('\u2191')); |
| 316 write(')'); | 323 write(')'); |
| 317 }); | 324 }); |
| 318 // TODO: Individual refactorings are not yet hyperlinked. | 325 // TODO: Individual refactorings are not yet hyperlinked. |
| 319 element('div', {'class': 'subindex'}, () { | 326 element('div', {'class': 'subindex'}, () { |
| 320 element('ul', {}, () { | 327 element('ul', {}, () { |
| 321 for (var refactoring in refactorings) { | 328 for (var refactoring in refactorings) { |
| (...skipping 15 matching lines...) Expand all Loading... |
| 337 element( | 344 element( |
| 338 'li', | 345 'li', |
| 339 {}, | 346 {}, |
| 340 () => link('request_${request.longMethod}', | 347 () => link('request_${request.longMethod}', |
| 341 () => write(request.method))); | 348 () => write(request.method))); |
| 342 } | 349 } |
| 343 } | 350 } |
| 344 }); | 351 }); |
| 345 } | 352 } |
| 346 | 353 |
| 347 void generateDomainsHeader() { | |
| 348 h1(() { | |
| 349 write('Domains'); | |
| 350 }); | |
| 351 } | |
| 352 | |
| 353 void generateTableOfContents() { | 354 void generateTableOfContents() { |
| 354 for (var domain in api.domains.where((domain) => !domain.experimental)) { | 355 for (var domain in api.domains.where((domain) => !domain.experimental)) { |
| 355 writeln(); | 356 writeln(); |
| 356 | 357 |
| 357 p(() { | 358 p(() { |
| 358 link('domain_${domain.name}', () { | 359 link('domain_${domain.name}', () { |
| 359 write(_toTitleCase(domain.name)); | 360 write(_toTitleCase(domain.name)); |
| 360 }); | 361 }); |
| 361 }); | 362 }); |
| 362 | 363 |
| (...skipping 12 matching lines...) Expand all Loading... |
| 375 } | 376 } |
| 376 } | 377 } |
| 377 | 378 |
| 378 void generateTypesIndex(Set<String> types) { | 379 void generateTypesIndex(Set<String> types) { |
| 379 h3(() { | 380 h3(() { |
| 380 write("Types"); | 381 write("Types"); |
| 381 write(' ('); | 382 write(' ('); |
| 382 link('types', () => write('\u2191')); | 383 link('types', () => write('\u2191')); |
| 383 write(')'); | 384 write(')'); |
| 384 }); | 385 }); |
| 386 List<String> sortedTypes = types.toList(); |
| 387 sortedTypes.sort(); |
| 385 element('div', {'class': 'subindex'}, () { | 388 element('div', {'class': 'subindex'}, () { |
| 386 element('ul', {}, () { | 389 element('ul', {}, () { |
| 387 for (var type in types) { | 390 for (var type in sortedTypes) { |
| 388 element('li', {}, () => link('type_$type', () => write(type))); | 391 element('li', {}, () => link('type_$type', () => write(type))); |
| 389 } | 392 } |
| 390 }); | 393 }); |
| 391 }); | 394 }); |
| 392 } | 395 } |
| 393 | 396 |
| 394 void javadocParams(TypeObject typeObject) { | 397 void javadocParams(TypeObject typeObject) { |
| 395 if (typeObject != null) { | 398 if (typeObject != null) { |
| 396 for (TypeObjectField field in typeObject.fields) { | 399 for (TypeObjectField field in typeObject.fields) { |
| 397 hangingIndent(() { | 400 hangingIndent(() { |
| (...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 471 case 'version': | 474 case 'version': |
| 472 translateHtml(node, squashParagraphs: squashParagraphs); | 475 translateHtml(node, squashParagraphs: squashParagraphs); |
| 473 break; | 476 break; |
| 474 case 'toc': | 477 case 'toc': |
| 475 generateTableOfContents(); | 478 generateTableOfContents(); |
| 476 break; | 479 break; |
| 477 case 'index': | 480 case 'index': |
| 478 generateIndex(); | 481 generateIndex(); |
| 479 break; | 482 break; |
| 480 default: | 483 default: |
| 481 if (!specialElements.contains(node.localName)) { | 484 if (!ApiReader.specialElements.contains(node.localName)) { |
| 482 element(node.localName, node.attributes, () { | 485 element(node.localName, node.attributes, () { |
| 483 translateHtml(node, squashParagraphs: squashParagraphs); | 486 translateHtml(node, squashParagraphs: squashParagraphs); |
| 484 }); | 487 }); |
| 485 } | 488 } |
| 486 } | 489 } |
| 487 } else if (node is dom.Text) { | 490 } else if (node is dom.Text) { |
| 488 String text = node.text; | 491 String text = node.text; |
| 489 write(text); | 492 write(text); |
| 490 } | 493 } |
| 491 } | 494 } |
| (...skipping 195 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 687 }); | 690 }); |
| 688 } | 691 } |
| 689 | 692 |
| 690 @override | 693 @override |
| 691 void visitTypeReference(TypeReference typeReference) {} | 694 void visitTypeReference(TypeReference typeReference) {} |
| 692 | 695 |
| 693 @override | 696 @override |
| 694 void visitTypes(Types types) { | 697 void visitTypes(Types types) { |
| 695 translateHtml(types.html); | 698 translateHtml(types.html); |
| 696 dl(() { | 699 dl(() { |
| 697 super.visitTypes(types); | 700 List<TypeDefinition> sortedTypes = types.toList(); |
| 701 sortedTypes.sort((TypeDefinition first, TypeDefinition second) => |
| 702 first.name.compareTo(second.name)); |
| 703 sortedTypes.forEach(visitTypeDefinition); |
| 698 }); | 704 }); |
| 699 } | 705 } |
| 700 } | 706 } |
| 701 | 707 |
| 702 /** | 708 /** |
| 703 * Visitor that generates a compact representation of a type, such as: | 709 * Visitor that generates a compact representation of a type, such as: |
| 704 * | 710 * |
| 705 * { | 711 * { |
| 706 * "id": String | 712 * "id": String |
| 707 * "error": optional Error | 713 * "error": optional Error |
| (...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 809 bool verticalBarNeeded = false; | 815 bool verticalBarNeeded = false; |
| 810 for (TypeDecl choice in typeUnion.choices) { | 816 for (TypeDecl choice in typeUnion.choices) { |
| 811 if (verticalBarNeeded) { | 817 if (verticalBarNeeded) { |
| 812 write(' | '); | 818 write(' | '); |
| 813 } | 819 } |
| 814 visitTypeDecl(choice); | 820 visitTypeDecl(choice); |
| 815 verticalBarNeeded = true; | 821 verticalBarNeeded = true; |
| 816 } | 822 } |
| 817 } | 823 } |
| 818 } | 824 } |
| OLD | NEW |