| 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; |
| (...skipping 18 matching lines...) Expand all Loading... |
| 29 margin: 0 auto; | 29 margin: 0 auto; |
| 30 padding: 0 16px; | 30 padding: 0 16px; |
| 31 font-size: 16px; | 31 font-size: 16px; |
| 32 line-height: 1.5; | 32 line-height: 1.5; |
| 33 color: #111; | 33 color: #111; |
| 34 background-color: #fdfdfd; | 34 background-color: #fdfdfd; |
| 35 font-weight: 300; | 35 font-weight: 300; |
| 36 -webkit-font-smoothing: auto; | 36 -webkit-font-smoothing: auto; |
| 37 } | 37 } |
| 38 | 38 |
| 39 h1 { | |
| 40 text-align: center; | |
| 41 } | |
| 42 | |
| 43 h2, h3, h4, h5 { | 39 h2, h3, h4, h5 { |
| 44 margin-bottom: 0; | 40 margin-bottom: 0; |
| 45 } | 41 } |
| 46 | 42 |
| 47 h2.domain { | 43 h2.domain { |
| 48 border-bottom: 1px solid rgb(200, 200, 200); | 44 border-bottom: 1px solid rgb(200, 200, 200); |
| 49 margin-bottom: 0.5em; | 45 margin-bottom: 0.5em; |
| 50 } | 46 } |
| 51 | 47 |
| 52 h4 { | 48 h4 { |
| (...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 108 } | 104 } |
| 109 | 105 |
| 110 a { | 106 a { |
| 111 text-decoration: none; | 107 text-decoration: none; |
| 112 } | 108 } |
| 113 | 109 |
| 114 a:focus, a:hover { | 110 a:focus, a:hover { |
| 115 text-decoration: underline; | 111 text-decoration: underline; |
| 116 } | 112 } |
| 117 | 113 |
| 114 .deprecated { |
| 115 text-decoration: line-through; |
| 116 } |
| 117 |
| 118 /* Styles for index */ | 118 /* Styles for index */ |
| 119 | 119 |
| 120 .subindex ul { | 120 .subindex ul { |
| 121 padding-left: 0; | 121 padding-left: 0; |
| 122 margin-left: 0; | 122 margin-left: 0; |
| 123 | 123 |
| 124 -webkit-margin-before: 0; | 124 -webkit-margin-before: 0; |
| 125 -webkit-margin-start: 0; | 125 -webkit-margin-start: 0; |
| 126 -webkit-padding-start: 0; | 126 -webkit-padding-start: 0; |
| 127 | 127 |
| (...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 193 | 193 |
| 194 void h3(void callback()) => element('h3', {}, callback); | 194 void h3(void callback()) => element('h3', {}, callback); |
| 195 void h4(void callback()) => element('h4', {}, callback); | 195 void h4(void callback()) => element('h4', {}, callback); |
| 196 void h5(void callback()) => element('h5', {}, callback); | 196 void h5(void callback()) => element('h5', {}, callback); |
| 197 void hangingIndent(void callback()) => | 197 void hangingIndent(void callback()) => |
| 198 element('div', {'class': 'hangingIndent'}, callback); | 198 element('div', {'class': 'hangingIndent'}, callback); |
| 199 void head(void callback()) => element('head', {}, callback); | 199 void head(void callback()) => element('head', {}, callback); |
| 200 void html(void callback()) => element('html', {}, callback); | 200 void html(void callback()) => element('html', {}, callback); |
| 201 void i(void callback()) => element('i', {}, callback); | 201 void i(void callback()) => element('i', {}, callback); |
| 202 void li(void callback()) => element('li', {}, callback); | 202 void li(void callback()) => element('li', {}, callback); |
| 203 void link(String id, void callback()) { | 203 void link(String id, void callback(), [Map<dynamic, String> attributes]) { |
| 204 element('a', {'href': '#$id'}, callback); | 204 attributes ??= {}; |
| 205 attributes['href'] = '#$id'; |
| 206 element('a', attributes, callback); |
| 205 } | 207 } |
| 206 | 208 |
| 207 void p(void callback()) => element('p', {}, callback); | 209 void p(void callback()) => element('p', {}, callback); |
| 208 void pre(void callback()) => element('pre', {}, callback); | 210 void pre(void callback()) => element('pre', {}, callback); |
| 209 void title(void callback()) => element('title', {}, callback); | 211 void title(void callback()) => element('title', {}, callback); |
| 210 void tt(void callback()) => element('tt', {}, callback); | 212 void tt(void callback()) => element('tt', {}, callback); |
| 211 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); |
| 212 } | 216 } |
| 213 | 217 |
| 214 /** | 218 /** |
| 215 * Visitor that generates HTML documentation of the API. | 219 * Visitor that generates HTML documentation of the API. |
| 216 */ | 220 */ |
| 217 class ToHtmlVisitor extends HierarchicalApiVisitor | 221 class ToHtmlVisitor extends HierarchicalApiVisitor |
| 218 with HtmlMixin, HtmlGenerator { | 222 with HtmlMixin, HtmlGenerator { |
| 219 /** | 223 /** |
| 220 * Set of types defined in the API. | 224 * Set of types defined in the API. |
| 221 */ | 225 */ |
| (...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 333 element( | 337 element( |
| 334 'li', | 338 'li', |
| 335 {}, | 339 {}, |
| 336 () => link('request_${request.longMethod}', | 340 () => link('request_${request.longMethod}', |
| 337 () => write(request.method))); | 341 () => write(request.method))); |
| 338 } | 342 } |
| 339 } | 343 } |
| 340 }); | 344 }); |
| 341 } | 345 } |
| 342 | 346 |
| 347 void generateDomainsHeader() { |
| 348 h1(() { |
| 349 write('Domains'); |
| 350 }); |
| 351 } |
| 352 |
| 343 void generateTableOfContents() { | 353 void generateTableOfContents() { |
| 344 ul(() { | 354 for (var domain in api.domains.where((domain) => !domain.experimental)) { |
| 345 writeln(); | 355 writeln(); |
| 346 | 356 |
| 347 for (var domain in api.domains.where((domain) => !domain.experimental)) { | 357 p(() { |
| 348 write(' '); | 358 link('domain_${domain.name}', () { |
| 349 li(() { | 359 write(_toTitleCase(domain.name)); |
| 350 link('domain_${domain.name}', () { | 360 }); |
| 351 write(_toTitleCase(domain.name)); | 361 }); |
| 362 |
| 363 ul(() { |
| 364 for (Request request in domain.requests) { |
| 365 li(() { |
| 366 link('request_${request.longMethod}', () { |
| 367 write(request.longMethod); |
| 368 }, request.deprecated ? {'class': 'deprecated'} : null); |
| 352 }); | 369 }); |
| 353 }); | 370 writeln(); |
| 354 writeln(); | 371 } |
| 355 } | 372 }); |
| 356 }); | 373 |
| 374 writeln(); |
| 375 } |
| 357 } | 376 } |
| 358 | 377 |
| 359 void generateTypesIndex(Set<String> types) { | 378 void generateTypesIndex(Set<String> types) { |
| 360 h3(() { | 379 h3(() { |
| 361 write("Types"); | 380 write("Types"); |
| 362 write(' ('); | 381 write(' ('); |
| 363 link('types', () => write('\u2191')); | 382 link('types', () => write('\u2191')); |
| 364 write(')'); | 383 write(')'); |
| 365 }); | 384 }); |
| 366 element('div', {'class': 'subindex'}, () { | 385 element('div', {'class': 'subindex'}, () { |
| (...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 416 * elements that define the API appropriately. | 435 * elements that define the API appropriately. |
| 417 */ | 436 */ |
| 418 void translateHtml(dom.Element html, {bool squashParagraphs: false}) { | 437 void translateHtml(dom.Element html, {bool squashParagraphs: false}) { |
| 419 for (dom.Node node in html.nodes) { | 438 for (dom.Node node in html.nodes) { |
| 420 if (node is dom.Element) { | 439 if (node is dom.Element) { |
| 421 if (squashParagraphs && node.localName == 'p') { | 440 if (squashParagraphs && node.localName == 'p') { |
| 422 translateHtml(node, squashParagraphs: squashParagraphs); | 441 translateHtml(node, squashParagraphs: squashParagraphs); |
| 423 continue; | 442 continue; |
| 424 } | 443 } |
| 425 switch (node.localName) { | 444 switch (node.localName) { |
| 445 case 'domains': |
| 446 generateDomainsHeader(); |
| 447 break; |
| 426 case 'domain': | 448 case 'domain': |
| 427 visitDomain(apiMappings.domains[node]); | 449 visitDomain(apiMappings.domains[node]); |
| 428 break; | 450 break; |
| 429 case 'head': | 451 case 'head': |
| 430 head(() { | 452 head(() { |
| 431 translateHtml(node, squashParagraphs: squashParagraphs); | 453 translateHtml(node, squashParagraphs: squashParagraphs); |
| 432 element('link', { | 454 element('link', { |
| 433 'rel': 'stylesheet', | 455 'rel': 'stylesheet', |
| 434 'href': | 456 'href': |
| 435 'https://fonts.googleapis.com/css?family=Source+Code+Pro|Rob
oto:500,400italic,300,400', | 457 'https://fonts.googleapis.com/css?family=Source+Code+Pro|Rob
oto:500,400italic,300,400', |
| (...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 508 }); | 530 }); |
| 509 } | 531 } |
| 510 } | 532 } |
| 511 | 533 |
| 512 @override | 534 @override |
| 513 void visitNotification(Notification notification) { | 535 void visitNotification(Notification notification) { |
| 514 dt('notification', () { | 536 dt('notification', () { |
| 515 anchor('notification_${notification.longEvent}', () { | 537 anchor('notification_${notification.longEvent}', () { |
| 516 write(notification.longEvent); | 538 write(notification.longEvent); |
| 517 }); | 539 }); |
| 518 write(' ('); | |
| 519 link('notification_${notification.longEvent}', () { | |
| 520 write('#'); | |
| 521 }); | |
| 522 write(')'); | |
| 523 }); | 540 }); |
| 524 dd(() { | 541 dd(() { |
| 525 box(() { | 542 box(() { |
| 526 showType( | 543 showType( |
| 527 'notification', notification.notificationType, notification.params); | 544 'notification', notification.notificationType, notification.params); |
| 528 }); | 545 }); |
| 529 translateHtml(notification.html); | 546 translateHtml(notification.html); |
| 530 describePayload(notification.params, 'parameters:'); | 547 describePayload(notification.params, 'parameters:'); |
| 531 }); | 548 }); |
| 532 } | 549 } |
| (...skipping 16 matching lines...) Expand all Loading... |
| 549 dl(() { | 566 dl(() { |
| 550 super.visitRefactorings(refactorings); | 567 super.visitRefactorings(refactorings); |
| 551 }); | 568 }); |
| 552 } | 569 } |
| 553 | 570 |
| 554 @override | 571 @override |
| 555 void visitRequest(Request request) { | 572 void visitRequest(Request request) { |
| 556 if (request.experimental) { | 573 if (request.experimental) { |
| 557 return; | 574 return; |
| 558 } | 575 } |
| 559 dt('request', () { | 576 dt(request.deprecated ? 'request deprecated' : 'request', () { |
| 560 anchor('request_${request.longMethod}', () { | 577 anchor('request_${request.longMethod}', () { |
| 561 write(request.longMethod); | 578 write(request.longMethod); |
| 562 }); | 579 }); |
| 563 write(' ('); | |
| 564 link('request_${request.longMethod}', () { | |
| 565 write('#'); | |
| 566 }); | |
| 567 write(')'); | |
| 568 }); | 580 }); |
| 569 dd(() { | 581 dd(() { |
| 570 box(() { | 582 box(() { |
| 571 showType('request', request.requestType, request.params); | 583 showType('request', request.requestType, request.params); |
| 572 br(); | 584 br(); |
| 573 showType('response', request.responseType, request.result); | 585 showType('response', request.responseType, request.result); |
| 574 }); | 586 }); |
| 575 translateHtml(request.html); | 587 translateHtml(request.html); |
| 576 describePayload(request.params, 'parameters:'); | 588 describePayload(request.params, 'parameters:'); |
| 577 describePayload(request.result, 'returns:'); | 589 describePayload(request.result, 'returns:'); |
| 578 }); | 590 }); |
| 579 } | 591 } |
| 580 | 592 |
| 581 @override | 593 @override |
| 582 void visitTypeDefinition(TypeDefinition typeDefinition) { | 594 void visitTypeDefinition(TypeDefinition typeDefinition) { |
| 583 if (typeDefinition.experimental) { | 595 if (typeDefinition.experimental) { |
| 584 return; | 596 return; |
| 585 } | 597 } |
| 586 dt('typeDefinition', () { | 598 dt( |
| 599 typeDefinition.deprecated |
| 600 ? 'typeDefinition deprecated' |
| 601 : 'typeDefinition', () { |
| 587 anchor('type_${typeDefinition.name}', () { | 602 anchor('type_${typeDefinition.name}', () { |
| 588 write('${typeDefinition.name}: '); | 603 write('${typeDefinition.name}: '); |
| 589 TypeVisitor typeVisitor = new TypeVisitor(api, short: true); | 604 TypeVisitor typeVisitor = new TypeVisitor(api, short: true); |
| 590 addAll(typeVisitor.collectHtml(() { | 605 addAll(typeVisitor.collectHtml(() { |
| 591 typeVisitor.visitTypeDecl(typeDefinition.type); | 606 typeVisitor.visitTypeDecl(typeDefinition.type); |
| 592 })); | 607 })); |
| 593 }); | 608 }); |
| 594 }); | 609 }); |
| 595 dd(() { | 610 dd(() { |
| 596 translateHtml(typeDefinition.html); | 611 translateHtml(typeDefinition.html); |
| (...skipping 11 matching lines...) Expand all Loading... |
| 608 @override | 623 @override |
| 609 void visitTypeEnumValue(TypeEnumValue typeEnumValue) { | 624 void visitTypeEnumValue(TypeEnumValue typeEnumValue) { |
| 610 bool isDocumented = false; | 625 bool isDocumented = false; |
| 611 for (dom.Node node in typeEnumValue.html.nodes) { | 626 for (dom.Node node in typeEnumValue.html.nodes) { |
| 612 if ((node is dom.Element && node.localName != 'code') || | 627 if ((node is dom.Element && node.localName != 'code') || |
| 613 (node is dom.Text && node.text.trim().isNotEmpty)) { | 628 (node is dom.Text && node.text.trim().isNotEmpty)) { |
| 614 isDocumented = true; | 629 isDocumented = true; |
| 615 break; | 630 break; |
| 616 } | 631 } |
| 617 } | 632 } |
| 618 dt('value', () { | 633 dt(typeEnumValue.deprecated ? 'value deprecated' : 'value', () { |
| 619 write(typeEnumValue.value); | 634 write(typeEnumValue.value); |
| 620 }); | 635 }); |
| 621 if (isDocumented) { | 636 if (isDocumented) { |
| 622 dd(() { | 637 dd(() { |
| 623 translateHtml(typeEnumValue.html); | 638 translateHtml(typeEnumValue.html); |
| 624 }); | 639 }); |
| 625 } | 640 } |
| 626 } | 641 } |
| 627 | 642 |
| 628 @override | 643 @override |
| (...skipping 10 matching lines...) Expand all Loading... |
| 639 void visitTypeObject(TypeObject typeObject) { | 654 void visitTypeObject(TypeObject typeObject) { |
| 640 dl(() { | 655 dl(() { |
| 641 super.visitTypeObject(typeObject); | 656 super.visitTypeObject(typeObject); |
| 642 }); | 657 }); |
| 643 } | 658 } |
| 644 | 659 |
| 645 @override | 660 @override |
| 646 void visitTypeObjectField(TypeObjectField typeObjectField) { | 661 void visitTypeObjectField(TypeObjectField typeObjectField) { |
| 647 dt('field', () { | 662 dt('field', () { |
| 648 b(() { | 663 b(() { |
| 649 write(typeObjectField.name); | 664 if (typeObjectField.deprecated) { |
| 665 span('deprecated', () { |
| 666 write(typeObjectField.name); |
| 667 }); |
| 668 } else { |
| 669 write(typeObjectField.name); |
| 670 } |
| 650 if (typeObjectField.value != null) { | 671 if (typeObjectField.value != null) { |
| 651 write(' = ${JSON.encode(typeObjectField.value)}'); | 672 write(' = ${JSON.encode(typeObjectField.value)}'); |
| 652 } else { | 673 } else { |
| 653 write(' ('); | 674 write(': '); |
| 654 if (typeObjectField.optional) { | |
| 655 gray(() { | |
| 656 write('optional'); | |
| 657 }); | |
| 658 write(' '); | |
| 659 } | |
| 660 TypeVisitor typeVisitor = new TypeVisitor(api, short: true); | 675 TypeVisitor typeVisitor = new TypeVisitor(api, short: true); |
| 661 addAll(typeVisitor.collectHtml(() { | 676 addAll(typeVisitor.collectHtml(() { |
| 662 typeVisitor.visitTypeDecl(typeObjectField.type); | 677 typeVisitor.visitTypeDecl(typeObjectField.type); |
| 663 })); | 678 })); |
| 664 write(')'); | 679 if (typeObjectField.optional) { |
| 680 gray(() => write(' (optional)')); |
| 681 } |
| 665 } | 682 } |
| 666 }); | 683 }); |
| 667 }); | 684 }); |
| 668 dd(() { | 685 dd(() { |
| 669 translateHtml(typeObjectField.html); | 686 translateHtml(typeObjectField.html); |
| 670 }); | 687 }); |
| 671 } | 688 } |
| 672 | 689 |
| 673 @override | 690 @override |
| 674 void visitTypeReference(TypeReference typeReference) {} | 691 void visitTypeReference(TypeReference typeReference) {} |
| (...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 792 bool verticalBarNeeded = false; | 809 bool verticalBarNeeded = false; |
| 793 for (TypeDecl choice in typeUnion.choices) { | 810 for (TypeDecl choice in typeUnion.choices) { |
| 794 if (verticalBarNeeded) { | 811 if (verticalBarNeeded) { |
| 795 write(' | '); | 812 write(' | '); |
| 796 } | 813 } |
| 797 visitTypeDecl(choice); | 814 visitTypeDecl(choice); |
| 798 verticalBarNeeded = true; | 815 verticalBarNeeded = true; |
| 799 } | 816 } |
| 800 } | 817 } |
| 801 } | 818 } |
| OLD | NEW |