From fb16b96ea6ee307e9edc7f9a927e6d734eb4004b Mon Sep 17 00:00:00 2001 From: Sorunome Date: Mon, 16 Aug 2021 17:37:19 +0200 Subject: [PATCH] fix: Correctly parse the reason of a spoiler Previously only the first child node of a spoiler was considered to determine if there should be a spoiler reason. This was, unfortunately, incorrect, as soon as e.g. the reason had more than one space. This is fixed by properly iterating all child nodes to search for the reason. --- lib/src/utils/markdown.dart | 34 ++++++++++++++++++++++++---------- test/markdown_test.dart | 6 ++++++ 2 files changed, 30 insertions(+), 10 deletions(-) diff --git a/lib/src/utils/markdown.dart b/lib/src/utils/markdown.dart index a13a4bf9..8ffd7a0a 100644 --- a/lib/src/utils/markdown.dart +++ b/lib/src/utils/markdown.dart @@ -37,21 +37,35 @@ class SpoilerSyntax extends TagSyntax { @override Node close(InlineParser parser, Delimiter opener, Delimiter closer, {List Function() getChildren}) { - var reason = ''; final children = getChildren(); - if (children.isNotEmpty) { - final te = children[0]; - if (te is Text) { - final tx = te.text; - final ix = tx.indexOf('|'); + final newChildren = []; + var searchingForReason = true; + var reason = ''; + for (final child in children) { + // If we already found a reason, let's just use our child nodes as-is + if (!searchingForReason) { + newChildren.add(child); + continue; + } + if (child is Text) { + final ix = child.text.indexOf('|'); if (ix > 0) { - reason = tx.substring(0, ix); - children[0] = Text(tx.substring(ix + 1)); + reason += child.text.substring(0, ix); + newChildren.add(Text(child.text.substring(ix + 1))); + searchingForReason = false; + } else { + reason += child.text; } + } else { + // if we don't have a text node as reason we just want to cancel this whole thing + break; } } - final element = Element('span', children); - element.attributes['data-mx-spoiler'] = htmlAttrEscape.convert(reason); + // if we were still searching for a reason that means there was none - use the original children! + final element = + Element('span', searchingForReason ? children : newChildren); + element.attributes['data-mx-spoiler'] = + searchingForReason ? '' : htmlAttrEscape.convert(reason); return element; } } diff --git a/test/markdown_test.dart b/test/markdown_test.dart index f509df08..c9e323a8 100644 --- a/test/markdown_test.dart +++ b/test/markdown_test.dart @@ -49,6 +49,12 @@ void main() { 'Snape killed Dumbledoor'); expect(markdown('Snape killed ||Story|Dumbledoor||'), 'Snape killed Dumbledoor'); + expect(markdown('Snape killed ||Some dumb loser|Dumbledoor||'), + 'Snape killed Dumbledoor'); + expect(markdown('Snape killed ||Some dumb loser|Dumbledoor **bold**||'), + 'Snape killed Dumbledoor bold'); + expect(markdown('Snape killed ||Dumbledoor **bold**||'), + 'Snape killed Dumbledoor bold'); }); test('multiple paragraphs', () { expect(markdown('Heya!\n\nBeep'), '

Heya!

\n

Beep

');