diff --git a/lib/model/content.dart b/lib/model/content.dart index 08ff476574..824d71eac6 100644 --- a/lib/model/content.dart +++ b/lib/model/content.dart @@ -1124,6 +1124,8 @@ class _ZulipContentParser { return result; } + static final _redundantLineBreaksRegexp = RegExp(r'^\n+$'); + List parseBlockContentList(dom.NodeList nodes) { assert(_debugParserContext == _ParserContext.block); final List result = []; @@ -1131,7 +1133,9 @@ class _ZulipContentParser { for (final node in nodes) { // We get a bunch of newline Text nodes between paragraphs. // A browser seems to ignore these; let's do the same. - if (node is dom.Text && (node.text == '\n')) continue; + if (node is dom.Text && _redundantLineBreaksRegexp.hasMatch(node.text)) { + continue; + } final block = parseBlockContent(node); if (block is ImageNode) { diff --git a/test/model/content_test.dart b/test/model/content_test.dart index eaddd70704..5a62f6e408 100644 --- a/test/model/content_test.dart +++ b/test/model/content_test.dart @@ -301,6 +301,17 @@ class ContentExample { '\n'), ]); + static const codeBlockFollowedByMultipleLineBreaks = ContentExample( + 'blank text nodes after code blocks', + ' code block.\n\nsome content', + // https://chat.zulip.org/#narrow/stream/7-test-here/near/1774823 + '
' + '
code block.\n
\n\n' + '

some content

', [ + CodeBlockNode([CodeBlockSpanNode(text: "code block.", type: CodeBlockSpanType.text)]), + ParagraphNode(links: null, nodes: [TextNode("some content")]), + ]); + static final mathInline = ContentExample.inline( 'inline math', r"$$ \lambda $$", @@ -865,6 +876,7 @@ void main() { testParseExample(ContentExample.codeBlockHighlightedMultiline); testParseExample(ContentExample.codeBlockWithHighlightedLines); testParseExample(ContentExample.codeBlockWithUnknownSpanType); + testParseExample(ContentExample.codeBlockFollowedByMultipleLineBreaks); testParseExample(ContentExample.mathBlock); testParseExample(ContentExample.mathBlockInQuote);