diff --git a/packages/flutter_markdown/lib/src/markdown_raw.dart b/packages/flutter_markdown/lib/src/markdown_raw.dart index 13fc714546..d100c397cb 100644 --- a/packages/flutter_markdown/lib/src/markdown_raw.dart +++ b/packages/flutter_markdown/lib/src/markdown_raw.dart @@ -129,10 +129,29 @@ class _MarkdownBodyRawState extends State { void initState() { super.initState(); + _buildMarkdownCache(); + } + void dispose() { + _linkHandler.dispose(); + super.dispose(); + } + + void didUpdateConfig(MarkdownBodyRaw oldConfig) { + super.didUpdateConfig(oldConfig); + + if (oldConfig.data != config.data || + oldConfig.markdownStyle != config.markdownStyle || + oldConfig.syntaxHighlighter != config.syntaxHighlighter || + oldConfig.onTapLink != config.onTapLink) + _buildMarkdownCache(); + } + + void _buildMarkdownCache() { MarkdownStyleRaw markdownStyle = config.markdownStyle ?? config.createDefaultStyle(context); SyntaxHighlighter syntaxHighlighter = config.syntaxHighlighter ?? new _DefaultSyntaxHighlighter(markdownStyle.code); + _linkHandler?.dispose(); _linkHandler = new _LinkHandler(config.onTapLink); // TODO: This can be optimized by doing the split and removing \r at the same time @@ -143,11 +162,6 @@ class _MarkdownBodyRawState extends State { _cachedBlocks = renderer.render(document.parseLines(lines), markdownStyle, syntaxHighlighter, _linkHandler); } - void dispose() { - _linkHandler.dispose(); - super.dispose(); - } - List<_Block> _cachedBlocks; _LinkHandler _linkHandler; @@ -162,6 +176,10 @@ class _MarkdownBodyRawState extends State { children: blocks ); } + + void debugFillDescription(List description) { + description.add('cached blocks identity: ${_cachedBlocks.hashCode}'); + } } class _Renderer implements md.NodeVisitor { diff --git a/packages/flutter_markdown/test/flutter_markdown_test.dart b/packages/flutter_markdown/test/flutter_markdown_test.dart index 72bc37f5a4..03c4204e0d 100644 --- a/packages/flutter_markdown/test/flutter_markdown_test.dart +++ b/packages/flutter_markdown/test/flutter_markdown_test.dart @@ -94,6 +94,37 @@ void main() { expect(span.children[0].recognizer.runtimeType, equals(TapGestureRecognizer)); }); }); + + test("Changing config - data", () { + testWidgets((WidgetTester tester) { + tester.pumpWidget(new Markdown(data: "Data1")); + _expectTextStrings(_listElements(tester), ["Data1"]); + + String stateBefore = WidgetFlutterBinding.instance.renderViewElement.toStringDeep(); + tester.pumpWidget(new Markdown(data: "Data1")); + String stateAfter = WidgetFlutterBinding.instance.renderViewElement.toStringDeep(); + expect(stateBefore, equals(stateAfter)); + + tester.pumpWidget(new Markdown(data: "Data2")); + _expectTextStrings(_listElements(tester), ["Data2"]); + }); + }); + + test("Changing config - style", () { + testWidgets((WidgetTester tester) { + ThemeData theme = new ThemeData.light(); + + MarkdownStyle style1 = new MarkdownStyle.defaultFromTheme(theme); + MarkdownStyle style2 = new MarkdownStyle.largeFromTheme(theme); + + tester.pumpWidget(new Markdown(data: "Test", markdownStyle: style1)); + + String stateBefore = WidgetFlutterBinding.instance.renderViewElement.toStringDeep(); + tester.pumpWidget(new Markdown(data: "Test", markdownStyle: style2)); + String stateAfter = WidgetFlutterBinding.instance.renderViewElement.toStringDeep(); + expect(stateBefore, isNot(stateAfter)); + }); + }); } List _listElements(WidgetTester tester) {