Skip to content

Commit

Permalink
Transform GitHub markdown task list's rendered <input> into icons.
Browse files Browse the repository at this point in the history
  • Loading branch information
isoos committed Sep 10, 2024
1 parent 905ceb3 commit 5eed4cd
Show file tree
Hide file tree
Showing 2 changed files with 45 additions and 0 deletions.
34 changes: 34 additions & 0 deletions app/lib/shared/markdown.dart
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,8 @@ String _renderSafeHtml(
}) {
// Filter unsafe urls on some of the elements.
nodes.forEach((node) => node.accept(_UnsafeUrlFilter()));
// Transform GitHub task lists.
nodes.forEach((node) => node.accept(_TaskListRewriteNodeVisitor()));

if (!disableHashIds) {
// add hash link HTML to header blocks
Expand Down Expand Up @@ -277,6 +279,38 @@ class _RelativeUrlRewriter implements m.NodeVisitor {
}
}

/// HTML sanitization will remove the rendered `<input type="checkbox">` elements,
/// we are replacing them with icons.
class _TaskListRewriteNodeVisitor implements m.NodeVisitor {
@override
void visitElementAfter(m.Element element) {
if (element.tag != 'li') {
return;
}
if (!(element.attributes['class']?.contains('task-list-item') ?? false)) {
return;
}
final children = element.children;
if (children == null || children.isEmpty) {
return null;
}
final first = children.first;
if (first is m.Element &&
first.tag == 'input' &&
first.attributes['type'] == 'checkbox') {
final checked = first.attributes['checked'] == 'true';
children.removeAt(0);
children.insert(0, m.Text(checked ? '✅ ' : '❌ '));
}
}

@override
bool visitElementBefore(m.Element element) => true;

@override
void visitText(m.Text text) {}
}

bool _isAbsolute(String url) => url.contains(':');

String _rewriteAbsoluteUrl(String url) {
Expand Down
11 changes: 11 additions & 0 deletions app/test/shared/markdown_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,17 @@ void main() {
expect(markdownToHtml('# ABC def'),
'<h1 class="hash-header" id="abc-def">ABC def <a href="#abc-def" class="hash-link">#</a></h1>\n');
});

test('task list', () {
expect(
markdownToHtml('- [ ] a\n- [X] b\n- [ ] c\n'),
'<ul>\n'
'<li>❌ a</li>\n'
'<li>✅ b</li>\n'
'<li>❌ c</li>\n'
'</ul>\n',
);
});
});

group('Valid custom base URL', () {
Expand Down

0 comments on commit 5eed4cd

Please sign in to comment.