Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
59 changes: 37 additions & 22 deletions app/lib/shared/markdown.dart
Original file line number Diff line number Diff line change
Expand Up @@ -52,10 +52,11 @@ String markdownToHtml(
urlResolverFn: urlResolverFn,
relativeFrom: relativeFrom,
);
if (isChangelog) {
nodes = _groupChangelogNodes(nodes).toList();
}
return _renderSafeHtml(nodes, disableHashIds: disableHashIds);
return _renderSafeHtml(
nodes,
isChangelog: isChangelog,
disableHashIds: disableHashIds,
);
} catch (e, st) {
_logger.shout('Error rendering markdown.', e, st);
// safe content inside the <pre> element
Expand Down Expand Up @@ -96,11 +97,13 @@ List<m.Node> _rewriteRelativeUrls(
/// Adds hash link HTML to header blocks.
String _renderSafeHtml(
List<m.Node> nodes, {
required bool isChangelog,
required bool disableHashIds,
}) {
final rawHtml = m.renderToHtml(nodes);
final processedHtml = _postProcessHtml(
rawHtml,
isChangelog: isChangelog,
disableHashIds: disableHashIds,
);

Expand All @@ -127,9 +130,16 @@ String _renderSafeHtml(

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

if (isChangelog) {
final oldNodes = [...root.nodes];
root = html.DocumentFragment();
_groupChangelogNodes(oldNodes).forEach(root.append);
}

// Filter unsafe urls on some of the elements.
_UnsafeUrlFilter().visit(root);
Expand Down Expand Up @@ -333,39 +343,44 @@ class _TaskListRewriteTreeVisitor extends html_parsing.TreeVisitor {
/// {{log entries in their original HTML format}}
/// </div>
/// </div>
Iterable<m.Node> _groupChangelogNodes(List<m.Node> nodes) sync* {
m.Element? lastContentDiv;
Iterable<html.Node> _groupChangelogNodes(List<html.Node> nodes) sync* {
html.Element? lastContentDiv;
String? firstHeaderTag;
for (final node in nodes) {
final nodeTag = node is m.Element ? node.tag : null;
final nodeTag = node is html.Element ? node.localName : null;
final isNewHeaderTag = firstHeaderTag == null &&
nodeTag != null &&
_structuralHeaderTags.contains(nodeTag);
final matchesFirstHeaderTag =
firstHeaderTag != null && nodeTag == firstHeaderTag;
final mayBeVersion = node is m.Element &&
final mayBeVersion = node is html.Element &&
(isNewHeaderTag || matchesFirstHeaderTag) &&
node.children!.isNotEmpty &&
node.children!.first is m.Text;
final versionText =
mayBeVersion ? node.children!.first.textContent.trim() : null;
node.nodes.isNotEmpty &&
node.nodes.first is html.Text;
final versionText = mayBeVersion ? node.nodes.first.text?.trim() : null;
final version = mayBeVersion ? _extractVersion(versionText) : null;
if (version != null) {
firstHeaderTag ??= nodeTag;
final titleElem = m.Element('h2', [m.Text(versionText!)])
final titleElem = html.Element.tag('h2')
..attributes['class'] = 'changelog-version'
..generatedId = (node as m.Element).generatedId;
..attributes['id'] = node.attributes['id']!
..append(html.Text(versionText!));

lastContentDiv = m.Element('div', [])
lastContentDiv = html.Element.tag('div')
..attributes['class'] = 'changelog-content';

yield m.Element('div', [
titleElem,
lastContentDiv,
])
..attributes['class'] = 'changelog-entry';
yield html.Element.tag('div')
..attributes['class'] = 'changelog-entry'
..append(html.Text('\n'))
..append(titleElem)
..append(html.Text('\n'))
..append(lastContentDiv);
} else if (lastContentDiv != null) {
lastContentDiv.children!.add(node);
final lastChild = lastContentDiv.nodes.lastOrNull;
if (lastChild is html.Element && lastChild.localName == 'div') {
lastContentDiv.append(html.Text('\n'));
}
lastContentDiv.append(node);
} else {
yield node;
}
Expand Down
12 changes: 6 additions & 6 deletions app/test/shared/markdown_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -304,8 +304,8 @@ void main() {
'<div class="changelog-content">\n'
'<ul>\n'
'<li>change1</li>\n'
'</ul>\n'
'</div>\n'
'</ul>'
'</div>'
'</div>\n');
});

Expand All @@ -324,13 +324,13 @@ void main() {
'<li>\n<p>change1</p>\n</li>\n'
'<li>\n<p>change2</p>\n</li>\n'
'</ul>\n'
'</div>\n'
'</div>\n'
'</div>'
'</div>'
'<div class="changelog-entry">\n'
'<h2 class="changelog-version hash-header" id="090">0.9.0 <a href="#090" class="hash-link">#</a></h2>\n'
'<div class="changelog-content">\n'
'<p>Mostly refactoring</p>\n'
'</div>\n'
'<p>Mostly refactoring</p>'
'</div>'
'</div>\n');
});

Expand Down
Loading