├── .gitignore
├── README.md
├── pubspec.yaml
├── example
├── legacy
│ ├── websocket.css
│ ├── sunflower.css
│ ├── websocket.html_snippet
│ ├── hello_world.dart
│ ├── sunflower.html_snippet
│ ├── fibonacci.dart
│ ├── websocket.dart
│ └── sunflower.dart
└── dart_2_1
│ ├── int_to_double.dart
│ └── new_mixin_syntax.dart
├── .travis.yml
├── test
├── legacy
│ ├── hello_world_test.dart
│ └── fibonacci_test.dart
└── dart_2_1
│ ├── int_to_double_test.dart
│ └── new_mixin_syntax_test.dart
├── LICENSE
├── CONTRIBUTING.md
├── analysis_options.yaml
└── tool
└── builder.dart
/.gitignore:
--------------------------------------------------------------------------------
1 | # Files and directories created by pub
2 | .dart_tool/
3 | .packages
4 | pubspec.lock
5 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | [](https://travis-ci.org/dart-lang/dartpad_examples)
2 |
3 | Nothing to see here...yet...
4 |
--------------------------------------------------------------------------------
/pubspec.yaml:
--------------------------------------------------------------------------------
1 | name: dartpad_examples
2 |
3 | environment:
4 | sdk: '>=2.1.0 <3.0.0'
5 |
6 | dev_dependencies:
7 | build: ^1.0.0
8 | build_runner: ^1.0.0
9 | build_web_compilers: '>=1.0.0 <3.0.0'
10 | path: ^1.0.0
11 | pedantic: ^1.0.0
12 | test: ^1.2.0
13 |
--------------------------------------------------------------------------------
/example/legacy/websocket.css:
--------------------------------------------------------------------------------
1 | /* Copyright 2015 the Dart project authors. All rights reserved. */
2 | /* Use of this source code is governed by a BSD-style license */
3 | /* that can be found in the LICENSE file. */
4 |
5 | input {
6 | width: 250px;
7 | margin-left: 2em;
8 | }
9 |
--------------------------------------------------------------------------------
/example/legacy/sunflower.css:
--------------------------------------------------------------------------------
1 | /* Copyright 2011 the Dart project authors. All rights reserved. */
2 | /* Use of this source code is governed by a BSD-style license */
3 | /* that can be found in the LICENSE file. */
4 |
5 | h2 {
6 | margin-bottom: 0;
7 | text-align: center;
8 | }
9 |
10 | div {
11 | text-align: center;
12 | }
13 |
--------------------------------------------------------------------------------
/example/legacy/websocket.html_snippet:
--------------------------------------------------------------------------------
1 |
4 |
5 |
A WebSocket test using echo.websocket.org
6 |
7 |
8 |
9 |
Enter text to echo:
10 |
11 |
12 |
--------------------------------------------------------------------------------
/.travis.yml:
--------------------------------------------------------------------------------
1 | language: dart
2 |
3 | dart:
4 | - 2.1.0
5 | - dev
6 |
7 | dart_task:
8 | - test: -p vm,chrome
9 | - dartfmt
10 | - dartanalyzer: --fatal-infos --fatal-warnings .
11 |
12 | # Only building master means that we don't run two builds for each pull request.
13 | branches:
14 | only: [master]
15 |
16 | cache:
17 | directories:
18 | - $HOME/.pub-cache
19 |
--------------------------------------------------------------------------------
/example/legacy/hello_world.dart:
--------------------------------------------------------------------------------
1 | // Copyright 2015 the Dart project authors. All rights reserved.
2 | // Use of this source code is governed by a BSD-style license
3 | // that can be found in the LICENSE file.
4 |
5 | //# Captured on 2018-10-09
6 | //# https://dartpad.dartlang.org/33706e19df021e52d98c
7 |
8 | void main() {
9 | for (var i = 0; i < 4; i++) {
10 | print('hello $i');
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/test/legacy/hello_world_test.dart:
--------------------------------------------------------------------------------
1 | // Copyright 2018 the Dart project authors. All rights reserved.
2 | // Use of this source code is governed by a BSD-style license
3 | // that can be found in the LICENSE file.
4 |
5 | import 'package:test/test.dart';
6 |
7 | import '../../example/legacy/hello_world.dart' as example;
8 |
9 | void main() {
10 | test('output', () {
11 | expect(example.main, prints(r'''
12 | hello 0
13 | hello 1
14 | hello 2
15 | hello 3
16 | '''));
17 | });
18 | }
19 |
--------------------------------------------------------------------------------
/example/legacy/sunflower.html_snippet:
--------------------------------------------------------------------------------
1 |
4 |
5 |
Dr. Fibonacci's Sunflower Spectacular
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
--------------------------------------------------------------------------------
/example/legacy/fibonacci.dart:
--------------------------------------------------------------------------------
1 | // Copyright 2015 the Dart project authors. All rights reserved.
2 | // Use of this source code is governed by a BSD-style license
3 | // that can be found in the LICENSE file.
4 |
5 | //# Captured on 2018-10-09
6 | //# https://dartpad.dartlang.org/74e990d984faad26dea0
7 |
8 | void main() {
9 | var i = 20;
10 | print('fibonacci($i) = ${fibonacci(i)}');
11 | }
12 |
13 | /// Computes the nth Fibonacci number.
14 | int fibonacci(int n) {
15 | return n < 2 ? n : (fibonacci(n - 1) + fibonacci(n - 2));
16 | }
17 |
--------------------------------------------------------------------------------
/test/legacy/fibonacci_test.dart:
--------------------------------------------------------------------------------
1 | // Copyright 2018 the Dart project authors. All rights reserved.
2 | // Use of this source code is governed by a BSD-style license
3 | // that can be found in the LICENSE file.
4 |
5 | import 'package:test/test.dart';
6 |
7 | import '../../example/legacy/fibonacci.dart' as example;
8 |
9 | void main() {
10 | test('output', () {
11 | expect(example.main, prints(r'''
12 | fibonacci(20) = 6765
13 | '''));
14 | });
15 |
16 | test('function', () {
17 | expect(example.fibonacci(10), 55);
18 | });
19 | }
20 |
--------------------------------------------------------------------------------
/test/dart_2_1/int_to_double_test.dart:
--------------------------------------------------------------------------------
1 | // Copyright 2018 the Dart project authors. All rights reserved.
2 | // Use of this source code is governed by a BSD-style license
3 | // that can be found in the LICENSE file.
4 |
5 | import 'dart:math' as math;
6 |
7 | import 'package:test/test.dart';
8 |
9 | import '../../example/dart_2_1/int_to_double.dart' as example;
10 |
11 | void main() {
12 | test('output', () {
13 | expect(example.main, prints(r'''
14 | 12.566370614359172
15 | 12.566370614359172
16 | '''));
17 | });
18 |
19 | test('api', () {
20 | var size = example.Circle(1);
21 | expect(size.radius, const TypeMatcher());
22 | expect(size.area, math.pi);
23 | });
24 | }
25 |
--------------------------------------------------------------------------------
/example/dart_2_1/int_to_double.dart:
--------------------------------------------------------------------------------
1 | // Copyright (c) 2018, the Dart project authors. Please see the AUTHORS file
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.
4 |
5 | import 'dart:math' as math;
6 |
7 | class Circle {
8 | double radius;
9 |
10 | Circle(this.radius);
11 |
12 | double get area => math.pi * math.pow(radius, 2);
13 | }
14 |
15 | void main() {
16 | // Before Dart 2.1, you had to provide a trailing `.0` – `42.0` – when
17 | // assigning to fields or parameters of type `double`.
18 | // A value like `42` was not allowed.
19 |
20 | print(Circle(2.0).area); // Before Dart 2.1, the trailing `.0` is required.
21 |
22 | // With Dart 2.1, you can provide whole-number values when assigning to
23 | // a double without the trailing `.0`.
24 | print(Circle(2).area); // Legal with Dart 2.1
25 | }
26 |
--------------------------------------------------------------------------------
/example/legacy/websocket.dart:
--------------------------------------------------------------------------------
1 | // Copyright 2012 the Dart project authors. All rights reserved.
2 | // Use of this source code is governed by a BSD-style license
3 | // that can be found in the LICENSE file.
4 |
5 | //# Captured on 2018-10-17
6 | //# https://dartpad.dartlang.org/479ecba5a56fd706b648
7 |
8 | import 'dart:html';
9 |
10 | void main() {
11 | var wsTest = WebSocketTest('wss://echo.websocket.org');
12 |
13 | InputElement input = querySelector('input');
14 | input.onChange.listen((_) {
15 | wsTest.send(input.value);
16 | input.value = '';
17 | });
18 | }
19 |
20 | class WebSocketTest {
21 | final WebSocket _socket;
22 | final _timer = Stopwatch()..start();
23 |
24 | WebSocketTest(String url) : _socket = WebSocket(url) {
25 | print('Connecting to $url...');
26 | _startListening();
27 | }
28 |
29 | void send(String value) {
30 | print('==> $value');
31 | _socket.send(value);
32 | _timer.reset();
33 | }
34 |
35 | void _startListening() {
36 | _socket.onOpen.listen((e) {
37 | print('Connected!');
38 | send('Hello from Dart!');
39 | });
40 |
41 | _socket.onClose.listen((_) => print('Websocket closed.'));
42 | _socket.onError.listen((_) => print('Error opening connection.'));
43 |
44 | _socket.onMessage.listen((e) {
45 | print('<== ${e.data} [${_timer.elapsedMilliseconds}ms]');
46 | });
47 | }
48 | }
49 |
--------------------------------------------------------------------------------
/test/dart_2_1/new_mixin_syntax_test.dart:
--------------------------------------------------------------------------------
1 | // Copyright 2018 the Dart project authors. All rights reserved.
2 | // Use of this source code is governed by a BSD-style license
3 | // that can be found in the LICENSE file.
4 |
5 | import 'package:test/test.dart';
6 |
7 | import '../../example/dart_2_1/new_mixin_syntax.dart' as example;
8 |
9 | void main() {
10 | test('output', () {
11 | expect(example.main, prints(r'''
12 | *
13 | * Simple usage of `mixin`
14 | *
15 |
16 | [ Answer ]
17 | - Use `with` to include a mixin
18 | answer: 42
19 |
20 | *
21 | * More advanced usage of `mixin`
22 | *
23 |
24 | [ LogAnswer ]
25 | - Include many mixins by separating with commas. `LoggingAnswerMixin` prints every time `answer` is accessed.
26 | LOG: `answer` property was accessed
27 | answer: 42
28 |
29 | *
30 | * The order in which mixins are included matters.
31 | *
32 |
33 | [ LogVerifyAnswer ]
34 | - In this case, log then verify.
35 | LOG: `answer` property was accessed
36 | VERIFY: Invalid Result!
37 | answer: 42
38 |
39 | [ VerifyLogAnswer ]
40 | - In this case, verify then log.
41 | VERIFY: Invalid Result!
42 | LOG: `answer` property was accessed
43 | answer: 42
44 |
45 | *
46 | * You can extend classes that include mixins, too.
47 | *
48 |
49 | [ DeltaLogVerifyAnswer ]
50 | - Verify will fail.
51 | LOG: `answer` property was accessed
52 | VERIFY: Invalid Result!
53 | answer: 42
54 |
55 | [ DeltaLogVerifyAnswer ]
56 | - Verify will succeed.
57 | LOG: `answer` property was accessed
58 | VERIFY: valid result
59 | answer: 43
60 |
61 | '''));
62 | });
63 | }
64 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | Copyright 2018, the Dart project authors. All rights reserved.
2 | Redistribution and use in source and binary forms, with or without
3 | modification, are permitted provided that the following conditions are
4 | met:
5 |
6 | * Redistributions of source code must retain the above copyright
7 | notice, this list of conditions and the following disclaimer.
8 | * Redistributions in binary form must reproduce the above
9 | copyright notice, this list of conditions and the following
10 | disclaimer in the documentation and/or other materials provided
11 | with the distribution.
12 | * Neither the name of Google Inc. nor the names of its
13 | contributors may be used to endorse or promote products derived
14 | from this software without specific prior written permission.
15 |
16 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17 | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18 | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19 | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20 | OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21 | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22 | LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 | THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 |
--------------------------------------------------------------------------------
/CONTRIBUTING.md:
--------------------------------------------------------------------------------
1 | Want to contribute? Great! First, read this page (including the small print at
2 | the end).
3 |
4 | ### Before you contribute
5 | Before we can use your code, you must sign the
6 | [Google Individual Contributor License Agreement](https://cla.developers.google.com/about/google-individual)
7 | (CLA), which you can do online. The CLA is necessary mainly because you own the
8 | copyright to your changes, even after your contribution becomes part of our
9 | codebase, so we need your permission to use and distribute your code. We also
10 | need to be sure of various other things—for instance that you'll tell us if you
11 | know that your code infringes on other people's patents. You don't have to sign
12 | the CLA until after you've submitted your code for review and a member has
13 | approved it, but you must do it before we can put your code into our codebase.
14 |
15 | Before you start working on a larger contribution, you should get in touch with
16 | us first through the issue tracker with your idea so that we can help out and
17 | possibly guide you. Coordinating up front makes it much easier to avoid
18 | frustration later on.
19 |
20 | ### Code reviews
21 | All submissions, including submissions by project members, require review.
22 |
23 | ### File headers
24 | All files in the project must start with the following header.
25 |
26 | // Copyright (c) 2018, the Dart project authors. Please see the AUTHORS file
27 | // for details. All rights reserved. Use of this source code is governed by a
28 | // BSD-style license that can be found in the LICENSE file.
29 |
30 | ### The small print
31 | Contributions made by corporations are covered by a different agreement than the
32 | one above, the
33 | [Software Grant and Corporate Contributor License Agreement](https://developers.google.com/open-source/cla/corporate).
34 |
--------------------------------------------------------------------------------
/example/legacy/sunflower.dart:
--------------------------------------------------------------------------------
1 | // Copyright 2011 the Dart project authors. All rights reserved.
2 | // Use of this source code is governed by a BSD-style license
3 | // that can be found in the LICENSE file.
4 |
5 | //# Captured on 2018-10-17
6 | //# https://dartpad.dartlang.org/49bde0c1ed780decc902f3d4d06d8f0c
7 |
8 | import 'dart:html';
9 | import 'dart:math' as math;
10 |
11 | void main() {
12 | Sunflower();
13 | }
14 |
15 | class Sunflower {
16 | static const orange = 'orange';
17 | static const seedRadius = 2;
18 | static const scaleFactor = 4;
19 | static const tau = math.pi * 2;
20 | static const maxD = 300;
21 |
22 | static final phi = (math.sqrt(5) + 1) / 2;
23 | static final center = maxD / 2;
24 |
25 | final context = (querySelector('#canvas') as CanvasElement).context2D;
26 |
27 | int seeds;
28 |
29 | Sunflower() {
30 | InputElement slider = querySelector('#slider');
31 |
32 | void update() {
33 | seeds = int.parse(slider.value);
34 | drawFrame();
35 | }
36 |
37 | slider.onChange.listen((_) => update());
38 |
39 | update();
40 | }
41 |
42 | // Draw the complete figure for the current number of seeds.
43 | void drawFrame() {
44 | print('seed value = $seeds');
45 |
46 | context.clearRect(0, 0, maxD, maxD);
47 |
48 | for (var i = 0; i < seeds; i++) {
49 | var theta = i * tau / phi;
50 | var r = math.sqrt(i) * scaleFactor;
51 | var x = center + r * math.cos(theta);
52 | var y = center - r * math.sin(theta);
53 | drawSeed(x, y);
54 | }
55 | }
56 |
57 | // Draw a small circle representing a seed centered at (x,y).
58 | void drawSeed(num x, num y) {
59 | context
60 | ..beginPath()
61 | ..lineWidth = 2
62 | ..fillStyle = orange
63 | ..strokeStyle = orange
64 | ..arc(x, y, seedRadius, 0, tau, false)
65 | ..fill()
66 | ..closePath()
67 | ..stroke();
68 | }
69 | }
70 |
--------------------------------------------------------------------------------
/analysis_options.yaml:
--------------------------------------------------------------------------------
1 | include: package:pedantic/analysis_options.yaml
2 | linter:
3 | rules:
4 | - annotate_overrides
5 | - avoid_empty_else
6 | - avoid_function_literals_in_foreach_calls
7 | - avoid_init_to_null
8 | - avoid_null_checks_in_equality_operators
9 | - avoid_relative_lib_imports
10 | - avoid_return_types_on_setters
11 | - avoid_returning_null
12 | - avoid_types_as_parameter_names
13 | - avoid_unused_constructor_parameters
14 | - await_only_futures
15 | - camel_case_types
16 | - cancel_subscriptions
17 | - cascade_invocations
18 | - comment_references
19 | - constant_identifier_names
20 | - control_flow_in_finally
21 | - directives_ordering
22 | - empty_catches
23 | - empty_constructor_bodies
24 | - empty_statements
25 | - hash_and_equals
26 | - implementation_imports
27 | - invariant_booleans
28 | - iterable_contains_unrelated_type
29 | - library_names
30 | - library_prefixes
31 | - list_remove_unrelated_type
32 | - no_adjacent_strings_in_list
33 | - no_duplicate_case_values
34 | - non_constant_identifier_names
35 | - omit_local_variable_types
36 | - only_throw_errors
37 | - overridden_fields
38 | - package_api_docs
39 | - package_names
40 | - package_prefixed_library_names
41 | - prefer_adjacent_string_concatenation
42 | - prefer_collection_literals
43 | - prefer_conditional_assignment
44 | - prefer_const_constructors
45 | - prefer_contains
46 | - prefer_equal_for_default_values
47 | - prefer_final_fields
48 | - prefer_initializing_formals
49 | - prefer_interpolation_to_compose_strings
50 | - prefer_is_empty
51 | - prefer_is_not_empty
52 | - prefer_single_quotes
53 | - prefer_typing_uninitialized_variables
54 | - recursive_getters
55 | - slash_for_doc_comments
56 | - test_types_in_equals
57 | - throw_in_finally
58 | - type_init_formals
59 | - unawaited_futures
60 | - unnecessary_brace_in_string_interps
61 | - unnecessary_const
62 | - unnecessary_getters_setters
63 | - unnecessary_lambdas
64 | - unnecessary_new
65 | - unnecessary_null_aware_assignments
66 | - unnecessary_statements
67 | - unnecessary_this
68 | - unrelated_type_equality_checks
69 | - use_rethrow_when_possible
70 | - valid_regexps
71 |
--------------------------------------------------------------------------------
/example/dart_2_1/new_mixin_syntax.dart:
--------------------------------------------------------------------------------
1 | // Copyright (c) 2018, the Dart project authors. Please see the AUTHORS file
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.
4 |
5 | mixin AnswerMixin {
6 | int get answer => 42;
7 |
8 | @override
9 | String toString() => '[ $runtimeType ]';
10 | }
11 |
12 | class Answer with AnswerMixin {}
13 |
14 | void main() {
15 | print('''
16 | *
17 | * Simple usage of `mixin`
18 | *
19 | ''');
20 | printAnswer(Answer(), 'Use `with` to include a mixin');
21 |
22 | print('''
23 | *
24 | * More advanced usage of `mixin`
25 | *
26 | ''');
27 | printAnswer(
28 | LogAnswer(),
29 | 'Include many mixins by separating with commas. '
30 | '`$LoggingAnswerMixin` prints every time `answer` is accessed.');
31 |
32 | print('''
33 | *
34 | * The order in which mixins are included matters.
35 | *
36 | ''');
37 |
38 | printAnswer(LogVerifyAnswer(), 'In this case, log then verify.');
39 | printAnswer(VerifyLogAnswer(), 'In this case, verify then log.');
40 |
41 | print('''
42 | *
43 | * You can extend classes that include mixins, too.
44 | *
45 | ''');
46 |
47 | printAnswer(DeltaLogVerifyAnswer(), 'Verify will fail.');
48 | printAnswer(DeltaLogVerifyAnswer(1), 'Verify will succeed.');
49 | }
50 |
51 | void printAnswer(AnswerMixin obj, String description) {
52 | print(obj);
53 | print('- $description');
54 | print('answer: ${obj.answer}');
55 | print('');
56 | }
57 |
58 | /// [LoggingAnswerMixin] can only be used as a mixin when the superclass
59 | /// (or one of the mixins that comes before it in a "with" clause) implements
60 | /// [AnswerMixin].
61 | mixin LoggingAnswerMixin on AnswerMixin {
62 | @override
63 | int get answer {
64 | var value = super.answer;
65 | print(' LOG: `answer` property was accessed');
66 | return value;
67 | }
68 | }
69 |
70 | class LogAnswer with AnswerMixin, LoggingAnswerMixin {}
71 |
72 | mixin VerifyingAnswerMixin on AnswerMixin {
73 | @override
74 | int get answer {
75 | var value = super.answer;
76 | if (value == 42) {
77 | print(' VERIFY: Invalid Result!');
78 | } else {
79 | print(' VERIFY: valid result');
80 | }
81 | return value;
82 | }
83 | }
84 |
85 | class LogVerifyAnswer
86 | with AnswerMixin, LoggingAnswerMixin, VerifyingAnswerMixin {}
87 |
88 | class VerifyLogAnswer
89 | with AnswerMixin, VerifyingAnswerMixin, LoggingAnswerMixin {}
90 |
91 | abstract class DeltaAnswer with AnswerMixin {
92 | final int delta;
93 |
94 | DeltaAnswer(this.delta);
95 |
96 | @override
97 | int get answer => super.answer + delta;
98 | }
99 |
100 | class DeltaLogVerifyAnswer extends DeltaAnswer
101 | with LoggingAnswerMixin, VerifyingAnswerMixin {
102 | DeltaLogVerifyAnswer([int delta = 0]) : super(delta);
103 | }
104 |
--------------------------------------------------------------------------------
/tool/builder.dart:
--------------------------------------------------------------------------------
1 | // Copyright (c) 2018, the Dart project authors. Please see the AUTHORS file
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.
4 |
5 | import 'dart:async';
6 | import 'dart:convert' show HtmlEscape, HtmlEscapeMode;
7 |
8 | import 'package:build/build.dart';
9 | import 'package:glob/glob.dart';
10 | import 'package:path/path.dart' as p;
11 |
12 | Builder exampleWebBuilder(BuilderOptions options) => _ExampleWebBuilder();
13 |
14 | Builder exampleRootBuilder(BuilderOptions options) => _WebRootBuilder();
15 |
16 | class _ExampleWebBuilder implements Builder {
17 | @override
18 | Future build(BuildStep buildStep) async {
19 | var source = await buildStep.readAsString(buildStep.inputId);
20 |
21 | var htmlAsset = buildStep.inputId.changeExtension('.html_snippet');
22 | String snippetContent;
23 | if (await buildStep.canRead(htmlAsset)) {
24 | snippetContent = await buildStep.readAsString(htmlAsset);
25 | }
26 |
27 | await buildStep.writeAsString(
28 | buildStep.inputId.changeExtension('.html'),
29 | _template(
30 | p.basenameWithoutExtension(buildStep.inputId.path),
31 | await buildStep.canRead(buildStep.inputId.changeExtension('.css')),
32 | const HtmlEscape(HtmlEscapeMode.element).convert(source),
33 | snippetContent ?? 'Open console...'));
34 | }
35 |
36 | @override
37 | final buildExtensions = const {
38 | '.dart': ['.html']
39 | };
40 |
41 | String _template(
42 | String name, bool hasCss, String source, String snippetContent) =>
43 | '''
44 |
45 |
46 |
47 |
48 |
49 | ${name.replaceAll('_', ' ')}
50 | ${hasCss ? '' : ''}
51 |
52 |
53 |
54 | $snippetContent
55 |
56 |