Skip to content

Commit

Permalink
[flutter_markdown] Fix mergeInlineChildren when first span is not a T…
Browse files Browse the repository at this point in the history
…extSpan (flutter#365)
  • Loading branch information
edhom authored Aug 1, 2021
1 parent c813f48 commit 5926d01
Show file tree
Hide file tree
Showing 4 changed files with 108 additions and 2 deletions.
4 changes: 4 additions & 0 deletions packages/flutter_markdown/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
## 0.6.4

* Fix merging of spans when first span is not a TextSpan

## 0.6.3

* Fixed `onTap`, now the changed hyperlinks are reflected even with keeping the same link name unchanged.
Expand Down
6 changes: 5 additions & 1 deletion packages/flutter_markdown/lib/src/builder.dart
Original file line number Diff line number Diff line change
Expand Up @@ -623,7 +623,11 @@ class MarkdownBuilder implements md.NodeVisitor {
final RichText previous = mergedTexts.removeLast() as RichText;
final TextSpan previousTextSpan = previous.text as TextSpan;
final List<TextSpan> children = previousTextSpan.children != null
? List<TextSpan>.from(previousTextSpan.children!)
? previousTextSpan.children!
.map((InlineSpan span) => span is! TextSpan
? TextSpan(children: <InlineSpan>[span])
: span)
.toList()
: <TextSpan>[previousTextSpan];
children.add(child.text as TextSpan);
final TextSpan? mergedSpan = _mergeSimilarTextSpans(children);
Expand Down
2 changes: 1 addition & 1 deletion packages/flutter_markdown/pubspec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ description: A Markdown renderer for Flutter. Create rich text output,
formatted with simple Markdown tags.
repository: https://github.com/flutter/packages/tree/master/packages/flutter_markdown
issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3A%22p%3A+flutter_markdown%22
version: 0.6.3
version: 0.6.4

environment:
sdk: ">=2.12.0 <3.0.0"
Expand Down
98 changes: 98 additions & 0 deletions packages/flutter_markdown/test/custom_syntax_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import 'package:flutter/widgets.dart';
import 'package:flutter_markdown/flutter_markdown.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:markdown/markdown.dart' as md;

import 'utils.dart';

void main() => defineTests();
Expand Down Expand Up @@ -58,7 +59,59 @@ void defineTests() {
expect(span.recognizer.runtimeType, equals(TapGestureRecognizer));
},
);

testWidgets(
'WidgetSpan in RichText is handled correctly',
(WidgetTester tester) async {
await tester.pumpWidget(
boilerplate(
Markdown(
data: 'container is a widget that allows to customize its child',
extensionSet: md.ExtensionSet.none,
inlineSyntaxes: <md.InlineSyntax>[ContainerSyntax()],
builders: <String, MarkdownElementBuilder>{
'container': ContainerBuilder(),
},
),
),
);

final RichText textWidget = tester.widget(find.byType(RichText));
final TextSpan span =
(textWidget.text as TextSpan).children![0] as TextSpan;
final WidgetSpan widgetSpan = span.children![0] as WidgetSpan;
expect(widgetSpan.child, isInstanceOf<Container>());
},
);
});

testWidgets(
'TextSpan and WidgetSpan as children in RichText are handled correctly',
(WidgetTester tester) async {
await tester.pumpWidget(
boilerplate(
Markdown(
data: 'this test replaces a string with a container',
extensionSet: md.ExtensionSet.none,
inlineSyntaxes: <md.InlineSyntax>[ContainerSyntax()],
builders: <String, MarkdownElementBuilder>{
'container': ContainerBuilder2(),
},
),
),
);

final RichText textWidget = tester.widget(find.byType(RichText));
final TextSpan textSpan = textWidget.text as TextSpan;
final TextSpan start = textSpan.children![0] as TextSpan;
expect(start.text, 'this test replaces a string with a ');
final TextSpan end = textSpan.children![1] as TextSpan;
final TextSpan foo = end.children![0] as TextSpan;
expect(foo.text, 'foo');
final WidgetSpan widgetSpan = end.children![1] as WidgetSpan;
expect(widgetSpan.child, isInstanceOf<Container>());
},
);
}

class SubscriptSyntax extends md.InlineSyntax {
Expand Down Expand Up @@ -126,3 +179,48 @@ class WikilinkBuilder extends MarkdownElementBuilder {
);
}
}

class ContainerSyntax extends md.InlineSyntax {
ContainerSyntax() : super(_pattern);

static const String _pattern = 'container';

@override
bool onMatch(md.InlineParser parser, Match match) {
parser.addNode(
md.Element.text('container', ''),
);
return true;
}
}

class ContainerBuilder extends MarkdownElementBuilder {
@override
Widget? visitElementAfter(md.Element element, _) {
return RichText(
text: TextSpan(
children: <InlineSpan>[
WidgetSpan(
child: Container(),
),
],
),
);
}
}

class ContainerBuilder2 extends MarkdownElementBuilder {
@override
Widget? visitElementAfter(md.Element element, _) {
return RichText(
text: TextSpan(
children: <InlineSpan>[
const TextSpan(text: 'foo'),
WidgetSpan(
child: Container(),
),
],
),
);
}
}

0 comments on commit 5926d01

Please sign in to comment.