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 |