Skip to content

Commit

Permalink
Migrate the hash-link markdown post-processing into the new HTML-node…
Browse files Browse the repository at this point in the history
… based version. (dart-lang#8597)
  • Loading branch information
isoos authored Feb 27, 2025
1 parent fa69d4d commit 23260c7
Show file tree
Hide file tree
Showing 13 changed files with 40 additions and 37 deletions.
47 changes: 25 additions & 22 deletions app/lib/shared/markdown.dart
Original file line number Diff line number Diff line change
Expand Up @@ -98,14 +98,11 @@ String _renderSafeHtml(
List<m.Node> nodes, {
required bool disableHashIds,
}) {
if (!disableHashIds) {
// add hash link HTML to header blocks
final hashLink = _HashLink();
nodes.forEach((node) => node.accept(hashLink));
}

final rawHtml = m.renderToHtml(nodes);
final processedHtml = _postProcessHtml(rawHtml);
final processedHtml = _postProcessHtml(
rawHtml,
disableHashIds: disableHashIds,
);

// Renders the sanitized HTML.
final html = sanitizeHtml(
Expand All @@ -128,7 +125,10 @@ String _renderSafeHtml(
return '$html\n';
}

String _postProcessHtml(String rawHtml) {
String _postProcessHtml(
String rawHtml, {
required bool disableHashIds,
}) {
final root = html_parser.parseFragment(rawHtml);

// Filter unsafe urls on some of the elements.
Expand All @@ -137,35 +137,38 @@ String _postProcessHtml(String rawHtml) {
// Transform GitHub task lists.
_TaskListRewriteTreeVisitor().visit(root);

if (!disableHashIds) {
// add hash link HTML to header blocks
_HashLink().visit(root);
}

return root.outerHtml;
}

/// Adds an extra <a href="#hash">#</a> element to h1, h2 and h3 elements.
class _HashLink implements m.NodeVisitor {
class _HashLink extends html_parsing.TreeVisitor {
@override
void visitText(m.Text text) {}
void visitElement(html.Element element) {
super.visitElement(element);

@override
bool visitElementBefore(m.Element element) => true;
final isHeaderWithHash = element.attributes.containsKey('id') &&
_structuralHeaderTags.contains(element.localName!);

@override
void visitElementAfter(m.Element element) {
final isHeaderWithHash = element.generatedId != null &&
_structuralHeaderTags.contains(element.tag);
if (isHeaderWithHash) {
_addHashLink(element, element.generatedId!);
_addHashLink(element, element.attributes['id']!);
}
}

void _addHashLink(m.Element element, String id) {
void _addHashLink(html.Element element, String id) {
final currentClasses = element.attributes['class'] ?? '';
element.attributes['class'] = '$currentClasses hash-header'.trim();
element.children!.addAll([
m.Text(' '),
m.Element('a', [m.Text('#')])
element.append(html.Text(' '));
element.append(
html.Element.tag('a')
..text = '#'
..attributes['href'] = '#$id'
..attributes['class'] = 'hash-link',
]);
);
}
}

Expand Down
2 changes: 1 addition & 1 deletion app/test/frontend/golden/help_page.html
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,7 @@ <h3 class="foldable-button">
<img class="standalone-side-image" src="/static/hash-%%etag%%/img/packages-side.webp" alt="" width="400" height="400" role="presentation"/>
</div>
<div class="standalone-content">
<h1 class="hash-header" id="help">
<h1 id="help" class="hash-header">
Help
<a href="#help" class="hash-link">#</a>
</h1>
Expand Down
2 changes: 1 addition & 1 deletion app/test/frontend/golden/pkg_show_page.html
Original file line number Diff line number Diff line change
Expand Up @@ -218,7 +218,7 @@ <h3 class="detail-lead-title">Metadata</h3>
<div class="detail-container detail-body-main">
<div class="detail-tabs-content">
<section class="tab-content detail-tab-readme-content -active markdown-body">
<h1 class="hash-header" id="oxygen">
<h1 id="oxygen" class="hash-header">
oxygen
<a href="#oxygen" class="hash-link">#</a>
</h1>
Expand Down
2 changes: 1 addition & 1 deletion app/test/frontend/golden/pkg_show_page_discontinued.html
Original file line number Diff line number Diff line change
Expand Up @@ -211,7 +211,7 @@ <h3 class="detail-lead-title">Metadata</h3>
<div class="detail-container detail-body-main">
<div class="detail-tabs-content">
<section class="tab-content detail-tab-readme-content -active markdown-body">
<h1 class="hash-header" id="pkg">
<h1 id="pkg" class="hash-header">
pkg
<a href="#pkg" class="hash-link">#</a>
</h1>
Expand Down
2 changes: 1 addition & 1 deletion app/test/frontend/golden/pkg_show_page_flutter_plugin.html
Original file line number Diff line number Diff line change
Expand Up @@ -207,7 +207,7 @@ <h3 class="detail-lead-title">Metadata</h3>
<div class="detail-container detail-body-main">
<div class="detail-tabs-content">
<section class="tab-content detail-tab-readme-content -active markdown-body">
<h1 class="hash-header" id="flutter_titanium">
<h1 id="flutter_titanium" class="hash-header">
flutter_titanium
<a href="#flutter_titanium" class="hash-link">#</a>
</h1>
Expand Down
2 changes: 1 addition & 1 deletion app/test/frontend/golden/pkg_show_page_publisher.html
Original file line number Diff line number Diff line change
Expand Up @@ -206,7 +206,7 @@ <h3 class="detail-lead-title">Metadata</h3>
<div class="detail-container detail-body-main">
<div class="detail-tabs-content">
<section class="tab-content detail-tab-readme-content -active markdown-body">
<h1 class="hash-header" id="neon">
<h1 id="neon" class="hash-header">
neon
<a href="#neon" class="hash-link">#</a>
</h1>
Expand Down
2 changes: 1 addition & 1 deletion app/test/frontend/golden/pkg_show_page_retracted.html
Original file line number Diff line number Diff line change
Expand Up @@ -194,7 +194,7 @@ <h3 class="detail-lead-title">Metadata</h3>
<div class="detail-container detail-body-main">
<div class="detail-tabs-content">
<section class="tab-content detail-tab-readme-content -active markdown-body">
<h1 class="hash-header" id="pkg">
<h1 id="pkg" class="hash-header">
pkg
<a href="#pkg" class="hash-link">#</a>
</h1>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -202,7 +202,7 @@ <h3 class="detail-lead-title">Metadata</h3>
<div class="detail-container detail-body-main">
<div class="detail-tabs-content">
<section class="tab-content detail-tab-readme-content -active markdown-body">
<h1 class="hash-header" id="pkg">
<h1 id="pkg" class="hash-header">
pkg
<a href="#pkg" class="hash-link">#</a>
</h1>
Expand Down
2 changes: 1 addition & 1 deletion app/test/frontend/golden/pkg_show_version_page.html
Original file line number Diff line number Diff line change
Expand Up @@ -212,7 +212,7 @@ <h3 class="detail-lead-title">Metadata</h3>
<div class="detail-container detail-body-main">
<div class="detail-tabs-content">
<section class="tab-content detail-tab-readme-content -active markdown-body">
<h1 class="hash-header" id="oxygen">
<h1 id="oxygen" class="hash-header">
oxygen
<a href="#oxygen" class="hash-link">#</a>
</h1>
Expand Down
8 changes: 4 additions & 4 deletions app/test/shared/markdown_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ void main() {

test('render link id and class', () {
expect(markdownToHtml('# ABC def'),
'<h1 class="hash-header" id="abc-def">ABC def <a href="#abc-def" class="hash-link">#</a></h1>\n');
'<h1 id="abc-def" class="hash-header">ABC def <a href="#abc-def" class="hash-link">#</a></h1>\n');
});

test('task list', () {
Expand Down Expand Up @@ -298,7 +298,7 @@ void main() {
'\n'
'- change1',
isChangelog: true),
'<h1 class="hash-header" id="changelog">Changelog <a href="#changelog" class="hash-link">#</a></h1>\n'
'<h1 id="changelog" class="hash-header">Changelog <a href="#changelog" class="hash-link">#</a></h1>\n'
'<div class="changelog-entry">\n'
'<h2 class="changelog-version hash-header" id="100">1.0.0 <a href="#100" class="hash-link">#</a></h2>\n'
'<div class="changelog-content">\n'
Expand All @@ -316,7 +316,7 @@ void main() {
'## 1.0.0\n\n- change1\n\n- change2\n\n'
'## 0.9.0\n\nMostly refactoring',
isChangelog: true),
'<h1 class="hash-header" id="changelog">Changelog <a href="#changelog" class="hash-link">#</a></h1>\n'
'<h1 id="changelog" class="hash-header">Changelog <a href="#changelog" class="hash-link">#</a></h1>\n'
'<div class="changelog-entry">\n'
'<h2 class="changelog-version hash-header" id="100">1.0.0 <a href="#100" class="hash-link">#</a></h2>\n'
'<div class="changelog-content">\n'
Expand Down Expand Up @@ -362,7 +362,7 @@ void main() {
expect(lines.where((l) => l.contains('changelog-version')), [
'<h2 class="changelog-version hash-header" id="210">2.1.0 <a href="#210" class="hash-link">#</a></h2>',
'<h2 class="changelog-version hash-header" id="200">2.0.0 <a href="#200" class="hash-link">#</a></h2>',
'<h2 class="changelog-version hash-header" id="100-2">1.0.0 <a href="#100" class="hash-link">#</a></h2>',
'<h2 class="changelog-version hash-header" id="100-2">1.0.0 <a href="#100-2" class="hash-link">#</a></h2>',
]);
});

Expand Down
2 changes: 1 addition & 1 deletion app/test/task/testdata/goldens/packages/oxygen.html
Original file line number Diff line number Diff line change
Expand Up @@ -204,7 +204,7 @@ <h3 class="detail-lead-title">Metadata</h3>
<div class="detail-container detail-body-main">
<div class="detail-tabs-content">
<section class="tab-content detail-tab-readme-content -active markdown-body">
<h1 class="hash-header" id="oxygen">
<h1 id="oxygen" class="hash-header">
oxygen
<a href="#oxygen" class="hash-link">#</a>
</h1>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -208,7 +208,7 @@ <h3 class="detail-lead-title">Metadata</h3>
<div class="detail-container detail-body-main">
<div class="detail-tabs-content">
<section class="tab-content detail-tab-readme-content -active markdown-body">
<h1 class="hash-header" id="oxygen">
<h1 id="oxygen" class="hash-header">
oxygen
<a href="#oxygen" class="hash-link">#</a>
</h1>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -204,7 +204,7 @@ <h3 class="detail-lead-title">Metadata</h3>
<div class="detail-container detail-body-main">
<div class="detail-tabs-content">
<section class="tab-content detail-tab-readme-content -active markdown-body">
<h1 class="hash-header" id="oxygen">
<h1 id="oxygen" class="hash-header">
oxygen
<a href="#oxygen" class="hash-link">#</a>
</h1>
Expand Down

0 comments on commit 23260c7

Please sign in to comment.