Skip to content

Added a custom function for creating image widgets #183

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions lib/flutter_html.dart
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ class Html extends StatelessWidget {
this.imageProperties,
this.onImageTap,
this.showImages = true,
this.customImgRender,
}) : super(key: key);

final String data;
Expand All @@ -43,6 +44,7 @@ class Html extends StatelessWidget {
final ImageErrorListener onImageError;
final TextStyle linkStyle;
final bool shrinkToFit;
final ImgRender customImgRender;

/// Properties for the Image widget that gets rendered by the rich text parser
final ImageProperties imageProperties;
Expand Down Expand Up @@ -80,6 +82,7 @@ class Html extends StatelessWidget {
imageProperties: imageProperties,
onImageTap: onImageTap,
showImages: showImages,
customImageRenderer: customImgRender,
)
: HtmlOldParser(
width: width,
Expand Down
107 changes: 69 additions & 38 deletions lib/rich_text_parser.dart
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,16 @@ import 'package:html/parser.dart' as parser;

import 'image_properties.dart';

typedef ImgRender = Widget Function({
String src,
String alt,
double width,
double height,
ImageProperties imageProperties,
bool shrinkToFit,
ParseContext nextContext,
});

typedef CustomRender = Widget Function(dom.Node node, List<Widget> children);
typedef CustomTextStyle = TextStyle Function(
dom.Node node,
Expand All @@ -20,6 +30,51 @@ typedef OnImageTap = void Function(String source);
const OFFSET_TAGS_FONT_SIZE_FACTOR =
0.7; //The ratio of the parent font for each of the offset tags: sup or sub

ImgRender _defaultImageRenderer = (
{String src,
String alt,
double width,
double height,
ImageProperties imageProperties,
bool shrinkToFit,
ParseContext nextContext}) {
return Image.network(
src,
frameBuilder: (context, child, frame, _) {
if (alt != null && frame == null) {
return BlockText(
child: RichText(
textAlign: TextAlign.center,
text: TextSpan(
text: alt,
style: nextContext.childStyle,
),
),
shrinkToFit: shrinkToFit,
);
}
if (frame != null) {
return child;
}
return Container();
},
width: (width ?? -1) > 0 ? width : null,
height: (height ?? -1) > 0 ? height : null,
scale: imageProperties?.scale ?? 1.0,
matchTextDirection: imageProperties?.matchTextDirection ?? false,
centerSlice: imageProperties?.centerSlice,
filterQuality: imageProperties?.filterQuality ?? FilterQuality.low,
alignment: imageProperties?.alignment ?? Alignment.center,
colorBlendMode: imageProperties?.colorBlendMode,
fit: imageProperties?.fit,
color: imageProperties?.color,
repeat: imageProperties?.repeat ?? ImageRepeat.noRepeat,
semanticLabel: imageProperties?.semanticLabel,
excludeFromSemantics:
(imageProperties?.semanticLabel == null) ? true : false,
);
};

class LinkTextSpan extends TextSpan {
// Beware!
//
Expand Down Expand Up @@ -165,6 +220,7 @@ class HtmlRichTextParser extends StatelessWidget {
this.imageProperties,
this.onImageTap,
this.showImages = true,
this.customImageRenderer,
});

final double indentSize = 10.0;
Expand All @@ -181,6 +237,7 @@ class HtmlRichTextParser extends StatelessWidget {
final ImageProperties imageProperties;
final OnImageTap onImageTap;
final bool showImages;
final ImgRender customImageRenderer;

// style elements set a default style
// for all child nodes
Expand Down Expand Up @@ -794,45 +851,19 @@ class HtmlRichTextParser extends StatelessWidget {
onError: onImageError ?? (_, __) {},
);
parseContext.rootWidgetList.add(GestureDetector(
child: Image.network(
node.attributes['src'],
frameBuilder: (context, child, frame, _) {
if (node.attributes['alt'] != null && frame == null) {
return BlockText(
child: RichText(
textAlign: TextAlign.center,
text: TextSpan(
text: node.attributes['alt'],
style: nextContext.childStyle,
),
),
child: customImageRenderer(
src: node.attributes['src'],
alt: node.attributes['alt'],
imageProperties: imageProperties,
shrinkToFit: shrinkToFit,
nextContext: nextContext,
) ??
_defaultImageRenderer(
src: node.attributes['src'],
alt: node.attributes['alt'],
imageProperties: imageProperties,
shrinkToFit: shrinkToFit,
);
}
if (frame != null) {
return child;
}
return Container();
},
width: (width ?? -1) > 0 ? width : null,
height: (height ?? -1) > 0 ? height : null,
scale: imageProperties?.scale ?? 1.0,
matchTextDirection:
imageProperties?.matchTextDirection ?? false,
centerSlice: imageProperties?.centerSlice,
filterQuality:
imageProperties?.filterQuality ?? FilterQuality.low,
alignment: imageProperties?.alignment ?? Alignment.center,
colorBlendMode: imageProperties?.colorBlendMode,
fit: imageProperties?.fit,
color: imageProperties?.color,
repeat: imageProperties?.repeat ?? ImageRepeat.noRepeat,
semanticLabel: imageProperties?.semanticLabel,
excludeFromSemantics:
(imageProperties?.semanticLabel == null)
? true
: false,
),
nextContext: nextContext),
onTap: () {
if (onImageTap != null) {
onImageTap(node.attributes['src']);
Expand Down