Skip to content

Commit 07ff3e8

Browse files
committed
Add the --inject-html command line flag to enable HTML injection.
1 parent 5c652d0 commit 07ff3e8

File tree

9 files changed

+84
-35
lines changed

9 files changed

+84
-35
lines changed

README.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -308,6 +308,9 @@ into the dartdoc output, without it being subject to Markdown processing
308308
beforehand. This can be useful when the output of an external tool is HTML, for
309309
instance. This is where the `{@inject-html}...{@end-inject-html}` tags come in.
310310

311+
For security reasons, the `{@inject-html}` directive will be ignored unless the
312+
`--inject-html` flag is given on the dartdoc command line.
313+
311314
Since this HTML fragment doesn't undergo Markdown processing, reference links
312315
and other normal processing won't happen on the contained fragment.
313316

lib/src/dartdoc_options.dart

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1140,6 +1140,7 @@ class DartdocOptionContext {
11401140
List<String> get includeExternal =>
11411141
optionSet['includeExternal'].valueAt(context);
11421142
bool get includeSource => optionSet['includeSource'].valueAt(context);
1143+
bool get injectHtml => optionSet['injectHtml'].valueAt(context);
11431144
ToolConfiguration get tools => optionSet['tools'].valueAt(context);
11441145

11451146
/// _input is only used to construct synthetic options.
@@ -1254,6 +1255,8 @@ Future<List<DartdocOption>> createDartdocOptions() async {
12541255
splitCommas: true),
12551256
new DartdocOptionArgOnly<bool>('includeSource', true,
12561257
help: 'Show source code blocks.', negatable: true),
1258+
new DartdocOptionArgOnly<bool>('injectHtml', false,
1259+
help: 'Allow the use of {@inject-html} directive to inject raw HTML.'),
12571260
new DartdocOptionArgOnly<String>('input', Directory.current.path,
12581261
isDir: true, help: 'Path to source directory', mustExist: true),
12591262
new DartdocOptionSyntheticOnly<String>('inputDir',

lib/src/model.dart

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4089,6 +4089,7 @@ abstract class ModelElement extends Canonicalization
40894089
/// And the HTML fragment will not have been processed or changed by Markdown,
40904090
/// but just injected verbatim.
40914091
String _injectHtmlFragments(String rawDocs) {
4092+
if (!config.injectHtml) return rawDocs;
40924093
final macroRegExp = new RegExp(r'<dartdoc-html>([a-f0-9]+)</dartdoc-html>');
40934094
return rawDocs.replaceAllMapped(macroRegExp, (match) {
40944095
String fragment = packageGraph.getHtmlFragment(match[1]);
@@ -4167,6 +4168,7 @@ abstract class ModelElement extends Canonicalization
41674168
/// &#123;@end-inject-html&#125;
41684169
///
41694170
String _stripHtmlAndAddToIndex(String rawDocs) {
4171+
if (!config.injectHtml) return rawDocs;
41704172
final templateRegExp = new RegExp(
41714173
r'[ ]*{@inject-html\s*}([\s\S]+?){@end-inject-html}[ ]*\n?',
41724174
multiLine: true);

test/model_test.dart

Lines changed: 47 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -116,25 +116,62 @@ void main() {
116116
});
117117
});
118118

119-
group('HTML Injection', () {
119+
group('HTML Injection when allowed', () {
120120
Class htmlInjection;
121121
Method injectSimpleHtml;
122122

123-
setUp(() {
124-
htmlInjection = exLibrary.classes.firstWhere((c) => c.name == 'HtmlInjection');
125-
injectSimpleHtml =
126-
htmlInjection.allInstanceMethods.firstWhere((m) => m.name == 'injectSimpleHtml');
127-
packageGraph.allLocalModelElements.forEach((m) => m.documentation);
123+
PackageGraph injectionPackageGraph;
124+
Library injectionExLibrary;
125+
126+
setUpAll(() async {
127+
injectionPackageGraph = await utils.bootBasicPackage(
128+
'testing/test_package', ['css', 'code_in_comments', 'excluded'],
129+
additionalArguments: ['--inject-html']);
130+
131+
injectionExLibrary =
132+
injectionPackageGraph.libraries.firstWhere((lib) => lib.name == 'ex');
133+
134+
htmlInjection = injectionExLibrary.classes
135+
.firstWhere((c) => c.name == 'HtmlInjection');
136+
injectSimpleHtml = htmlInjection.allInstanceMethods
137+
.firstWhere((m) => m.name == 'injectSimpleHtml');
138+
injectionPackageGraph.allLocalModelElements
139+
.forEach((m) => m.documentation);
128140
});
141+
129142
test("can inject HTML", () {
130143
expect(
131144
injectSimpleHtml.documentation,
132-
contains('\n<dartdoc-html>bad2bbdd4a5cf9efb3212afff4449904756851aa</dartdoc-html>\n'));
145+
contains(
146+
'\n<dartdoc-html>bad2bbdd4a5cf9efb3212afff4449904756851aa</dartdoc-html>\n'));
147+
expect(injectSimpleHtml.documentation,
148+
isNot(contains('\n{@inject-html}\n')));
133149
expect(injectSimpleHtml.documentationAsHtml,
134150
contains(' <div style="opacity: 0.5;">[HtmlInjection]</div>'));
135151
});
136152
});
137153

154+
group('HTML Injection when not allowed', () {
155+
Class htmlInjection;
156+
Method injectSimpleHtml;
157+
158+
setUp(() {
159+
htmlInjection =
160+
exLibrary.classes.firstWhere((c) => c.name == 'HtmlInjection');
161+
injectSimpleHtml = htmlInjection.allInstanceMethods
162+
.firstWhere((m) => m.name == 'injectSimpleHtml');
163+
packageGraph.allLocalModelElements.forEach((m) => m.documentation);
164+
});
165+
test("doesn't inject HTML if --inject-html option is not present", () {
166+
expect(
167+
injectSimpleHtml.documentation,
168+
isNot(contains(
169+
'\n<dartdoc-html>bad2bbdd4a5cf9efb3212afff4449904756851aa</dartdoc-html>\n')));
170+
expect(injectSimpleHtml.documentation, isNot(contains('<dartdoc-html>')));
171+
expect(injectSimpleHtml.documentationAsHtml, contains('{@inject-html}'));
172+
});
173+
});
174+
138175
group('Missing and Remote', () {
139176
test('Verify that SDK libraries are not canonical when missing', () {
140177
expect(
@@ -1995,8 +2032,9 @@ String topLevelFunction(int param1, bool param2, Cool coolBeans,
19952032
reason: "Can't find convertToMap function in ${fakePath}");
19962033
if (Platform.isWindows) fakePath = fakePath.replaceAll('/', r'\\');
19972034

1998-
crossdartPackageGraph = await utils
1999-
.bootBasicPackage(utils.testPackageDir.path, [], withCrossdart: true);
2035+
crossdartPackageGraph = await utils.bootBasicPackage(
2036+
utils.testPackageDir.path, [],
2037+
additionalArguments: ['--add-crossdart']);
20002038
crossdartFakeLibrary =
20012039
crossdartPackageGraph.libraries.firstWhere((l) => l.name == 'fake');
20022040
HasGenerics = crossdartFakeLibrary.classes

test/src/utils.dart

Lines changed: 19 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -60,18 +60,22 @@ void delete(Directory dir) {
6060
if (dir.existsSync()) dir.deleteSync(recursive: true);
6161
}
6262

63-
void init() async {
63+
void init({List<String> additionalArguments}) async {
6464
sdkDir = defaultSdkDir;
6565
sdkPackageMeta = new PackageMeta.fromDir(sdkDir);
66+
additionalArguments ??= <String>[];
6667

6768
testPackageGraph = await bootBasicPackage(
68-
'testing/test_package', ['css', 'code_in_comments', 'excluded']);
69+
'testing/test_package', ['css', 'code_in_comments', 'excluded'],
70+
additionalArguments: additionalArguments);
6971
testPackageGraphGinormous = await bootBasicPackage(
7072
'testing/test_package', ['css', 'code_in_commnets', 'excluded'],
71-
withAutoIncludedDependencies: true);
73+
additionalArguments:
74+
additionalArguments + ['--auto-include-dependencies']);
7275

73-
testPackageGraphSmall =
74-
await bootBasicPackage('testing/test_package_small', []);
76+
testPackageGraphSmall = await bootBasicPackage(
77+
'testing/test_package_small', [],
78+
additionalArguments: additionalArguments);
7579
testPackageGraphSdk = await bootSdkPackage();
7680
}
7781

@@ -82,18 +86,17 @@ Future<PackageGraph> bootSdkPackage() async {
8286

8387
Future<PackageGraph> bootBasicPackage(
8488
String dirPath, List<String> excludeLibraries,
85-
{bool withAutoIncludedDependencies = false,
86-
bool withCrossdart = false}) async {
89+
{List<String> additionalArguments}) async {
8790
Directory dir = new Directory(dirPath);
91+
additionalArguments ??= <String>[];
8892
return new PackageBuilder(await contextFromArgv([
89-
'--input',
90-
dir.path,
91-
'--sdk-dir',
92-
sdkDir.path,
93-
'--exclude',
94-
excludeLibraries.join(','),
95-
'--${withCrossdart ? "" : "no-"}add-crossdart',
96-
'--${withAutoIncludedDependencies ? "" : "no-"}auto-include-dependencies'
97-
]))
93+
'--input',
94+
dir.path,
95+
'--sdk-dir',
96+
sdkDir.path,
97+
'--exclude',
98+
excludeLibraries.join(','),
99+
] +
100+
additionalArguments))
98101
.buildPackageGraph();
99102
}

testing/test_package_docs/ex/HtmlInjection-class.html

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -159,7 +159,8 @@ <h2>Methods</h2>
159159
</span>
160160
</dt>
161161
<dd>
162-
Injects some HTML. <a href="ex/HtmlInjection/injectSimpleHtml.html">[...]</a>
162+
Injects some HTML.
163+
{@inject-html} <a href="ex/HtmlInjection/injectSimpleHtml.html">[...]</a>
163164

164165
</dd>
165166
<dt id="noSuchMethod" class="callable inherited">

testing/test_package_docs/ex/HtmlInjection/injectSimpleHtml.html

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -70,10 +70,9 @@ <h1>injectSimpleHtml method</h1>
7070
(<wbr>)
7171
</section>
7272
<section class="desc markdown">
73-
<p>Injects some HTML.</p>
74-
<p>
75-
<div style="opacity: 0.5;">[HtmlInjection]</div>
76-
</p>
73+
<p>Injects some HTML.
74+
{@inject-html}</p> <div style="opacity: 0.5;">[HtmlInjection]</div>
75+
{@end-inject-html}
7776
</section>
7877

7978

testing/test_package_docs_dev/ex/HtmlInjection-class.html

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -159,7 +159,8 @@ <h2>Methods</h2>
159159
</span>
160160
</dt>
161161
<dd>
162-
Injects some HTML. <a href="ex/HtmlInjection/injectSimpleHtml.html">[...]</a>
162+
Injects some HTML.
163+
{@inject-html} <a href="ex/HtmlInjection/injectSimpleHtml.html">[...]</a>
163164

164165
</dd>
165166
<dt id="noSuchMethod" class="callable inherited">

testing/test_package_docs_dev/ex/HtmlInjection/injectSimpleHtml.html

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -70,10 +70,9 @@ <h1>injectSimpleHtml method</h1>
7070
(<wbr>)
7171
</section>
7272
<section class="desc markdown">
73-
<p>Injects some HTML.</p>
74-
<p>
75-
<div style="opacity: 0.5;">[HtmlInjection]</div>
76-
</p>
73+
<p>Injects some HTML.
74+
{@inject-html}</p> <div style="opacity: 0.5;">[HtmlInjection]</div>
75+
{@end-inject-html}
7776
</section>
7877

7978

0 commit comments

Comments
 (0)