Merge pull request #61 from trieutritam/support-uri-data-scheme

Support URI data scheme in Image
diff --git a/packages/flutter_markdown/lib/src/builder.dart b/packages/flutter_markdown/lib/src/builder.dart
index bc40497..059bbad 100644
--- a/packages/flutter_markdown/lib/src/builder.dart
+++ b/packages/flutter_markdown/lib/src/builder.dart
@@ -260,6 +260,8 @@
     Widget child;
     if (uri.scheme == 'http' || uri.scheme == 'https') {
       child = new Image.network(uri.toString(), width: width, height: height);
+    } else if (uri.scheme == 'data') {
+      child = _handleDataSchemeUri(uri, width, height);
     } else {
       String filePath = (imageDirectory == null
           ? uri.toFilePath()
@@ -275,6 +277,16 @@
     }
   }
 
+  Widget _handleDataSchemeUri(Uri uri, final double width, final double height) {
+    final String mimeType = uri.data.mimeType;
+    if (mimeType.startsWith('image/')) {
+      return new Image.memory(uri.data.contentAsBytes(), width: width, height: height);
+    } else if (mimeType.startsWith('text/')) {
+      return new Text(uri.data.contentAsString());
+    }
+    return const SizedBox();
+  }
+
   Widget _buildBullet(String listTag) {
     if (listTag == 'ul')
       return new Text('•', textAlign: TextAlign.center, style: styleSheet.styles['li']);
diff --git a/packages/flutter_markdown/test/flutter_markdown_test.dart b/packages/flutter_markdown/test/flutter_markdown_test.dart
index f71902c..ca341f6 100644
--- a/packages/flutter_markdown/test/flutter_markdown_test.dart
+++ b/packages/flutter_markdown/test/flutter_markdown_test.dart
@@ -323,6 +323,61 @@
     });
   });
 
+  group('uri data scheme', () {
+    testWidgets('should work with image in uri data scheme', (WidgetTester tester) async {
+      const String imageData = '![alt](data:image/gif;base64,R0lGODlhAQABAIAAAAUEBAAAACwAAAAAAQABAAACAkQBADs=)';
+      await tester
+          .pumpWidget(_boilerplate(const Markdown(data: imageData)));
+
+      final Image image =
+      tester.allWidgets.firstWhere((Widget widget) => widget is Image);
+      expect(image.image.runtimeType, MemoryImage);
+    });
+
+    testWidgets('should work with base64 text in uri data scheme', (WidgetTester tester) async {
+      const String imageData = '![alt](data:text/plan;base64,Rmx1dHRlcg==)';
+      await tester
+          .pumpWidget(_boilerplate(const Markdown(data: imageData)));
+
+      final Text widget =
+      tester.allWidgets.firstWhere((Widget widget) => widget is Text);
+      expect(widget.runtimeType, Text);
+      expect(widget.data, 'Flutter');
+    });
+
+    testWidgets('should work with text in uri data scheme', (WidgetTester tester) async {
+      const String imageData = '![alt](data:text/plan,Hello%2C%20Flutter)';
+      await tester
+          .pumpWidget(_boilerplate(const Markdown(data: imageData)));
+
+      final Text widget =
+      tester.allWidgets.firstWhere((Widget widget) => widget is Text);
+      expect(widget.runtimeType, Text);
+      expect(widget.data, 'Hello, Flutter');
+    });
+
+    testWidgets('should work with empty uri data scheme', (WidgetTester tester) async {
+      const String imageData = '![alt](data:,)';
+      await tester
+          .pumpWidget(_boilerplate(const Markdown(data: imageData)));
+
+      final Text widget =
+      tester.allWidgets.firstWhere((Widget widget) => widget is Text);
+      expect(widget.runtimeType, Text);
+      expect(widget.data, '');
+    });
+
+    testWidgets('should work with unsupported mime types of uri data scheme', (WidgetTester tester) async {
+      const String imageData = '![alt](data:application/javascript,var%20test=1)';
+      await tester
+          .pumpWidget(_boilerplate(const Markdown(data: imageData)));
+
+      final SizedBox widget =
+      tester.allWidgets.firstWhere((Widget widget) => widget is SizedBox);
+      expect(widget.runtimeType, SizedBox);
+    });
+  });
+
   testWidgets('HTML tag ignored ', (WidgetTester tester) async {
     final List<String> mdData = <String>[
       'Line 1\n<p>HTML content</p>\nLine 2',