+{@end-inject-html}
diff --git a/dev/snippets/lib/configuration.dart b/dev/snippets/lib/configuration.dart
index 1f401b1bfd9a17..e1f65fd9e858a7 100644
--- a/dev/snippets/lib/configuration.dart
+++ b/dev/snippets/lib/configuration.dart
@@ -67,8 +67,12 @@ class Configuration {
/// dartdoc.
Directory get templatesDirectory => Directory(path.join(configDirectory.path, 'templates'));
- /// Gets the skeleton file to use for the given [SnippetType].
- File getHtmlSkeletonFile(SnippetType type) {
- return File(path.join(skeletonsDirectory.path, '${getEnumName(type)}.html'));
+ /// Gets the skeleton file to use for the given [SnippetType] and DartPad preference.
+ File getHtmlSkeletonFile(SnippetType type, {bool showDartPad = false}) {
+ assert(!showDartPad || type == SnippetType.application,
+ 'Only application snippets work with dartpad.');
+ final String filename =
+ '${showDartPad ? 'dartpad-' : ''}${getEnumName(type)}.html';
+ return File(path.join(skeletonsDirectory.path, filename));
}
}
diff --git a/dev/snippets/lib/main.dart b/dev/snippets/lib/main.dart
index 996b186c9bbd9e..6af06617ed8c1b 100644
--- a/dev/snippets/lib/main.dart
+++ b/dev/snippets/lib/main.dart
@@ -20,6 +20,7 @@ const String _kOutputOption = 'output';
const String _kPackageOption = 'package';
const String _kTemplateOption = 'template';
const String _kTypeOption = 'type';
+const String _kShowDartPad = 'dartpad';
/// Generates snippet dartdoc output for a given input, and creates any sample
/// applications needed by the snippet.
@@ -87,6 +88,14 @@ void main(List argList) {
negatable: false,
help: 'Prints help documentation for this command',
);
+ parser.addFlag(
+ _kShowDartPad,
+ defaultsTo: false,
+ negatable: false,
+ help: 'Indicates whether DartPad should be included in the snippet\'s '
+ 'final HTML output. This flag only applies when the type parameter is '
+ '"application".',
+ );
final ArgResults args = parser.parse(argList);
@@ -99,6 +108,11 @@ void main(List argList) {
.firstWhere((SnippetType type) => getEnumName(type) == args[_kTypeOption], orElse: () => null);
assert(snippetType != null, "Unable to find '${args[_kTypeOption]}' in SnippetType enum.");
+ if (args[_kShowDartPad] == true && snippetType != SnippetType.application) {
+ errorExit('${args[_kTypeOption]} was selected, but the --dartpad flag is only valid '
+ 'for application snippets.');
+ }
+
if (args[_kInputOption] == null) {
stderr.writeln(parser.usage);
errorExit('The --$_kInputOption option must be specified, either on the command '
@@ -151,6 +165,7 @@ void main(List argList) {
stdout.write(generator.generate(
input,
snippetType,
+ showDartPad: args[_kShowDartPad],
template: template,
output: args[_kOutputOption] != null ? File(args[_kOutputOption]) : null,
metadata: {
diff --git a/dev/snippets/lib/snippets.dart b/dev/snippets/lib/snippets.dart
index 05d54f4c16979a..22721060522101 100644
--- a/dev/snippets/lib/snippets.dart
+++ b/dev/snippets/lib/snippets.dart
@@ -202,6 +202,11 @@ class SnippetGenerator {
/// The [type] is the type of snippet to create: either a
/// [SnippetType.application] or a [SnippetType.sample].
///
+ /// [showDartPad] indicates whether DartPad should be shown where possible.
+ /// Currently, this value only has an effect if [type] is
+ /// [SnippetType.application], in which case an alternate skeleton file is
+ /// used to create the final HTML output.
+ ///
/// The [template] must not be null if the [type] is
/// [SnippetType.application], and specifies the name of the template to use
/// for the application code.
@@ -212,6 +217,7 @@ class SnippetGenerator {
String generate(
File input,
SnippetType type, {
+ bool showDartPad = false,
String template,
File output,
@required Map metadata,
@@ -219,6 +225,8 @@ class SnippetGenerator {
assert(template != null || type != SnippetType.application);
assert(metadata != null && metadata['id'] != null);
assert(input != null);
+ assert(!showDartPad || type == SnippetType.application,
+ 'Only application snippets work with dartpad.');
final List<_ComponentTuple> snippetData = parseInput(_loadFileAsUtf8(input));
switch (type) {
case SnippetType.application:
@@ -266,7 +274,8 @@ class SnippetGenerator {
case SnippetType.sample:
break;
}
- final String skeleton = _loadFileAsUtf8(configuration.getHtmlSkeletonFile(type));
+ final String skeleton =
+ _loadFileAsUtf8(configuration.getHtmlSkeletonFile(type, showDartPad: showDartPad));
return interpolateSkeleton(type, snippetData, skeleton, metadata);
}
}
diff --git a/dev/snippets/test/configuration_test.dart b/dev/snippets/test/configuration_test.dart
index 41e7d2f7df6cec..f4879d751095bd 100644
--- a/dev/snippets/test/configuration_test.dart
+++ b/dev/snippets/test/configuration_test.dart
@@ -31,11 +31,23 @@ void main() {
expect(config.templatesDirectory.path,
matches(RegExp(r'[/\\]flutter sdk[/\\]dev[/\\]snippets[/\\]config[/\\]templates')));
});
- test('html skeleton file is correct', () async {
+ test('html skeleton file for sample is correct', () async {
+ expect(
+ config.getHtmlSkeletonFile(SnippetType.sample).path,
+ matches(RegExp(
+ r'[/\\]flutter sdk[/\\]dev[/\\]snippets[/\\]config[/\\]skeletons[/\\]sample.html')));
+ });
+ test('html skeleton file for app with no dartpad is correct', () async {
expect(
config.getHtmlSkeletonFile(SnippetType.application).path,
matches(RegExp(
r'[/\\]flutter sdk[/\\]dev[/\\]snippets[/\\]config[/\\]skeletons[/\\]application.html')));
});
+ test('html skeleton file for app with dartpad is correct', () async {
+ expect(
+ config.getHtmlSkeletonFile(SnippetType.application, showDartPad: true).path,
+ matches(RegExp(
+ r'[/\\]flutter sdk[/\\]dev[/\\]snippets[/\\]config[/\\]skeletons[/\\]dartpad-application.html')));
+ });
});
}
diff --git a/dev/snippets/test/snippets_test.dart b/dev/snippets/test/snippets_test.dart
index f3cb758a3cc2de..73ca67ea4c207d 100644
--- a/dev/snippets/test/snippets_test.dart
+++ b/dev/snippets/test/snippets_test.dart
@@ -48,6 +48,11 @@ main() {
{{description}}
'));
+ expect(html, contains(''));
+ });
+
test('generates snippet application metadata', () async {
final File inputFile = File(path.join(tmpDir.absolute.path, 'snippet_in.txt'))
..createSync(recursive: true)
diff --git a/packages/flutter/lib/src/material/app_bar.dart b/packages/flutter/lib/src/material/app_bar.dart
index c4a47127a1d958..bad79ac93a4552 100644
--- a/packages/flutter/lib/src/material/app_bar.dart
+++ b/packages/flutter/lib/src/material/app_bar.dart
@@ -89,7 +89,7 @@ class _ToolbarContainerLayout extends SingleChildLayoutDelegate {
/// to false. In that case a null leading widget will result in the middle/title widget
/// stretching to start.
///
-/// {@tool snippet --template=stateless_widget_material}
+/// {@tool dartpad --template=stateless_widget_material}
///
/// This sample shows an [AppBar] with two simple actions. The first action
/// opens a [SnackBar], while the second action navigates to a new page.