From 52e105716bebbeaeef1545de199d66f923402f33 Mon Sep 17 00:00:00 2001 From: sinexy Date: Mon, 9 Jan 2023 17:29:20 +0800 Subject: [PATCH 1/4] add the property(`loadingWidget`) to fix 'https://github.com/Sub6Resources/flutter_html/issues/1180' --- lib/custom_render.dart | 5 +++-- lib/flutter_html.dart | 21 +++++++++++++++++++-- 2 files changed, 22 insertions(+), 4 deletions(-) diff --git a/lib/custom_render.dart b/lib/custom_render.dart index abb1931418..00d340c4e5 100644 --- a/lib/custom_render.dart +++ b/lib/custom_render.dart @@ -10,6 +10,7 @@ import 'package:flutter_html/src/html_elements.dart'; import 'package:flutter_html/src/utils.dart'; typedef CustomRenderMatcher = bool Function(RenderContext context); +typedef ImageLoadingBuilder = Widget Function(); CustomRenderMatcher tagMatcher(String tag) => (context) { return context.tree.element?.localName == tag; @@ -437,14 +438,14 @@ CustomRender fallbackRender({Style? style, List? children}) => .toList(), )); -Map generateDefaultRenders() { +Map generateDefaultRenders({ImageLoadingBuilder? loadingWidget}) { return { blockElementMatcher(): blockElementRender(), listElementMatcher(): listElementRender(), textContentElementMatcher(): textContentElementRender(), dataUriMatcher(): base64ImageRender(), assetUriMatcher(): assetImageRender(), - networkSourceMatcher(): networkImageRender(), + networkSourceMatcher(): networkImageRender(loadingWidget: loadingWidget), replacedElementMatcher(): replacedElementRender(), interactableElementMatcher(): interactableElementRender(), layoutElementMatcher(): layoutElementRender(), diff --git a/lib/flutter_html.dart b/lib/flutter_html.dart index 1b5d7fe55e..a8f5563d4d 100644 --- a/lib/flutter_html.dart +++ b/lib/flutter_html.dart @@ -23,6 +23,8 @@ export 'package:flutter_html/src/css_box_widget.dart'; //export style api export 'package:flutter_html/style.dart'; +typedef ImageLoadingBuilder = Widget Function(); + class Html extends StatefulWidget { /// The `Html` widget takes HTML as input and displays a RichText /// tree of the parsed HTML content. @@ -60,6 +62,7 @@ class Html extends StatefulWidget { this.onImageError, this.shrinkWrap = false, this.onImageTap, + this.loadingBuilder, this.tagsList = const [], this.style = const {}, }) : documentElement = null, @@ -76,6 +79,7 @@ class Html extends StatefulWidget { this.customRenders = const {}, this.onCssParseError, this.onImageError, + this.loadingBuilder, this.shrinkWrap = false, this.onImageTap, this.tagsList = const [], @@ -97,6 +101,7 @@ class Html extends StatefulWidget { this.onImageError, this.shrinkWrap = false, this.onImageTap, + this.loadingBuilder, this.tagsList = const [], this.style = const {}, }) : data = null, @@ -136,6 +141,12 @@ class Html extends StatefulWidget { /// A list of HTML tags that are the only tags that are rendered. By default, this list is empty and all supported HTML tags are rendered. final List tagsList; + /// A builder that specifies the widget to display to the user while an image + /// is still loading. + /// If this is null, By default to show + /// a [CircularProgressIndicator] while an image loads over the network. + final ImageLoadingBuilder? loadingBuilder; + /// Either return a custom widget for specific node types or return null to /// fallback to the default rendering. final Map customRenders; @@ -192,7 +203,7 @@ class _HtmlState extends State { style: widget.style, customRenders: {} ..addAll(widget.customRenders) - ..addAll(generateDefaultRenders()), + ..addAll(generateDefaultRenders(loadingWidget: widget.loadingBuilder)), tagsList: widget.tagsList.isEmpty ? Html.tags : widget.tagsList, ); } @@ -323,6 +334,12 @@ class SelectableHtml extends StatefulWidget { /// Allows you to override the default scrollPhysics for [SelectableText.rich] final ScrollPhysics? scrollPhysics; + /// A builder that specifies the widget to display to the user while an image + /// is still loading. + /// If this is null, By default to show + /// a [CircularProgressIndicator] while an image loads over the network. + final ImageLoadingBuilder? loadingBuilder; + /// Either return a custom widget for specific node types or return null to /// fallback to the default rendering. final Map customRenders; @@ -362,7 +379,7 @@ class _SelectableHtmlState extends State { style: widget.style, customRenders: {} ..addAll(widget.customRenders) - ..addAll(generateDefaultRenders()), + ..addAll(generateDefaultRenders(loadingWidget: widget.loadingBuilder)), tagsList: widget.tagsList.isEmpty ? SelectableHtml.tags : widget.tagsList, selectionControls: widget.selectionControls, From 16e3c133098bfa563544e894cea3b168aa5a6e34 Mon Sep 17 00:00:00 2001 From: sinexy Date: Tue, 17 Jan 2023 14:36:29 +0800 Subject: [PATCH 2/4] add the property to Named constructors --- lib/flutter_html.dart | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/lib/flutter_html.dart b/lib/flutter_html.dart index a8f5563d4d..ae4393fc5e 100644 --- a/lib/flutter_html.dart +++ b/lib/flutter_html.dart @@ -254,6 +254,7 @@ class SelectableHtml extends StatefulWidget { this.tagsList = const [], this.selectionControls, this.scrollPhysics, + this.loadingBuilder, }) : documentElement = null, assert(data != null), _anchorKey = anchorKey ?? GlobalKey(), @@ -272,6 +273,7 @@ class SelectableHtml extends StatefulWidget { this.tagsList = const [], this.selectionControls, this.scrollPhysics, + this.loadingBuilder, }) : data = null, assert(document != null), documentElement = document!.documentElement, @@ -291,6 +293,7 @@ class SelectableHtml extends StatefulWidget { this.tagsList = const [], this.selectionControls, this.scrollPhysics, + this.loadingBuilder, }) : data = null, assert(documentElement != null), _anchorKey = anchorKey ?? GlobalKey(), @@ -379,7 +382,8 @@ class _SelectableHtmlState extends State { style: widget.style, customRenders: {} ..addAll(widget.customRenders) - ..addAll(generateDefaultRenders(loadingWidget: widget.loadingBuilder)), + ..addAll( + generateDefaultRenders(loadingWidget: widget.loadingBuilder)), tagsList: widget.tagsList.isEmpty ? SelectableHtml.tags : widget.tagsList, selectionControls: widget.selectionControls, From 8771105c30daceca9be60753aa63ede59aafbd32 Mon Sep 17 00:00:00 2001 From: sinexy Date: Tue, 17 Jan 2023 15:07:30 +0800 Subject: [PATCH 3/4] remove the typedef ImageLoadingBuilder = Widget Function(); --- lib/custom_render.dart | 3 ++- lib/flutter_html.dart | 2 -- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/lib/custom_render.dart b/lib/custom_render.dart index 00d340c4e5..73e016151e 100644 --- a/lib/custom_render.dart +++ b/lib/custom_render.dart @@ -438,7 +438,8 @@ CustomRender fallbackRender({Style? style, List? children}) => .toList(), )); -Map generateDefaultRenders({ImageLoadingBuilder? loadingWidget}) { +Map generateDefaultRenders( + {ImageLoadingBuilder? loadingWidget}) { return { blockElementMatcher(): blockElementRender(), listElementMatcher(): listElementRender(), diff --git a/lib/flutter_html.dart b/lib/flutter_html.dart index ae4393fc5e..387b635b24 100644 --- a/lib/flutter_html.dart +++ b/lib/flutter_html.dart @@ -23,8 +23,6 @@ export 'package:flutter_html/src/css_box_widget.dart'; //export style api export 'package:flutter_html/style.dart'; -typedef ImageLoadingBuilder = Widget Function(); - class Html extends StatefulWidget { /// The `Html` widget takes HTML as input and displays a RichText /// tree of the parsed HTML content. From 4fee7004adcdf7db1f2e20cefe7f497b00e95728 Mon Sep 17 00:00:00 2001 From: sinexy Date: Tue, 17 Jan 2023 15:15:45 +0800 Subject: [PATCH 4/4] add unit_test --- test/flutter_html_test.dart | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/test/flutter_html_test.dart b/test/flutter_html_test.dart index 30acdbe449..4c0eddca39 100644 --- a/test/flutter_html_test.dart +++ b/test/flutter_html_test.dart @@ -10,6 +10,9 @@ void main() { MaterialApp( home: Html( data: "", + loadingBuilder: (){ + return Container(); + }, ), ), ); @@ -24,6 +27,9 @@ void main() { MaterialApp( home: SelectableHtml( data: '', + loadingBuilder: (){ + return Container(); + }, ), ), ); @@ -38,6 +44,9 @@ void main() { MaterialApp( home: Html( data: "Text", + loadingBuilder: (){ + return Container(); + }, ), ), ); @@ -101,6 +110,9 @@ void main() { home: Html( data: "Text", tagsList: Html.tags..add('custom'), + loadingBuilder: (){ + return Container(); + }, ), ), );