From c5f396dd29b9ede943d1e908b48d4b80ac2d2542 Mon Sep 17 00:00:00 2001 From: Zak Barbuto Date: Mon, 25 Oct 2021 17:43:30 +1030 Subject: [PATCH 001/111] Add support for auto horizontal margins Allow centering images with auto-margins --- example/lib/main.dart | 18 +++- lib/html_parser.dart | 53 ++++++----- lib/src/css_parser.dart | 68 ++++++++++--- lib/src/styled_element.dart | 32 +++---- lib/style.dart | 95 ++++++++++++++++++- .../lib/flutter_html_table.dart | 2 +- 6 files changed, 209 insertions(+), 59 deletions(-) diff --git a/example/lib/main.dart b/example/lib/main.dart index 550ad15bd1..cd5f87704c 100644 --- a/example/lib/main.dart +++ b/example/lib/main.dart @@ -55,10 +55,20 @@ const htmlData = r"""

The should be BLACK with 10% alpha style='color: rgba(0, 0, 0, 0.10);

The should be GREEN style='color: rgb(0, 97, 0);

The should be GREEN style='color: rgb(0, 97, 0);

-

blasdafjklasdlkjfkl

-

blasdafjklasdlkjfkl

-

blasdafjklasdlkjfkl

-

blasdafjklasdlkjfkl

+

Text Alignment

+

Center Aligned Text

+

Right Aligned Text

+

Justified Text

+

Center Aligned Text

+

Auto Margins

+
Default Div
+
margin: auto
+
margin: 15px auto
+
margin-left: auto
+

With an image - non-block (should not center):

+ +

block image (should center):

+

Table support (with custom styling!):

Famous quote... diff --git a/lib/html_parser.dart b/lib/html_parser.dart index fdfcf4cbd1..e2eabfb967 100644 --- a/lib/html_parser.dart +++ b/lib/html_parser.dart @@ -650,7 +650,7 @@ class HtmlParser extends StatelessWidget { if (tree.children.isEmpty) { // Handle case (4) from above. if ((tree.style.height ?? 0) == 0) { - tree.style.margin = EdgeInsets.zero; + tree.style.margin = tree.style.margin?.collapse() ?? Margins.zero; } return tree; } @@ -666,47 +666,47 @@ class HtmlParser extends StatelessWidget { // Handle case (1) from above. // Top margins cannot collapse if the element has padding if ((tree.style.padding?.top ?? 0) == 0) { - final parentTop = tree.style.margin?.top ?? 0; - final firstChildTop = tree.children.first.style.margin?.top ?? 0; + final parentTop = tree.style.margin?.top?.value ?? 0; + final firstChildTop = tree.children.first.style.margin?.top?.value ?? 0; final newOuterMarginTop = max(parentTop, firstChildTop); // Set the parent's margin if (tree.style.margin == null) { - tree.style.margin = EdgeInsets.only(top: newOuterMarginTop); + tree.style.margin = Margins.only(top: newOuterMarginTop); } else { - tree.style.margin = tree.style.margin!.copyWith(top: newOuterMarginTop); + tree.style.margin = tree.style.margin!.copyWithEdge(top: newOuterMarginTop); } // And remove the child's margin if (tree.children.first.style.margin == null) { - tree.children.first.style.margin = EdgeInsets.zero; + tree.children.first.style.margin = Margins.zero; } else { tree.children.first.style.margin = - tree.children.first.style.margin!.copyWith(top: 0); + tree.children.first.style.margin!.copyWithEdge(top: 0); } } // Handle case (3) from above. // Bottom margins cannot collapse if the element has padding if ((tree.style.padding?.bottom ?? 0) == 0) { - final parentBottom = tree.style.margin?.bottom ?? 0; - final lastChildBottom = tree.children.last.style.margin?.bottom ?? 0; + final parentBottom = tree.style.margin?.bottom?.value ?? 0; + final lastChildBottom = tree.children.last.style.margin?.bottom?.value ?? 0; final newOuterMarginBottom = max(parentBottom, lastChildBottom); // Set the parent's margin if (tree.style.margin == null) { - tree.style.margin = EdgeInsets.only(bottom: newOuterMarginBottom); + tree.style.margin = Margins.only(bottom: newOuterMarginBottom); } else { tree.style.margin = - tree.style.margin!.copyWith(bottom: newOuterMarginBottom); + tree.style.margin!.copyWithEdge(bottom: newOuterMarginBottom); } // And remove the child's margin if (tree.children.last.style.margin == null) { - tree.children.last.style.margin = EdgeInsets.zero; + tree.children.last.style.margin = Margins.zero; } else { tree.children.last.style.margin = - tree.children.last.style.margin!.copyWith(bottom: 0); + tree.children.last.style.margin!.copyWithEdge(bottom: 0); } } @@ -714,24 +714,24 @@ class HtmlParser extends StatelessWidget { if (tree.children.length > 1) { for (int i = 1; i < tree.children.length; i++) { final previousSiblingBottom = - tree.children[i - 1].style.margin?.bottom ?? 0; - final thisTop = tree.children[i].style.margin?.top ?? 0; + tree.children[i - 1].style.margin?.bottom?.value ?? 0; + final thisTop = tree.children[i].style.margin?.top?.value ?? 0; final newInternalMargin = max(previousSiblingBottom, thisTop) / 2; if (tree.children[i - 1].style.margin == null) { tree.children[i - 1].style.margin = - EdgeInsets.only(bottom: newInternalMargin); + Margins.only(bottom: newInternalMargin); } else { tree.children[i - 1].style.margin = tree.children[i - 1].style.margin! - .copyWith(bottom: newInternalMargin); + .copyWithEdge(bottom: newInternalMargin); } if (tree.children[i].style.margin == null) { tree.children[i].style.margin = - EdgeInsets.only(top: newInternalMargin); + Margins.only(top: newInternalMargin); } else { tree.children[i].style.margin = - tree.children[i].style.margin!.copyWith(top: newInternalMargin); + tree.children[i].style.margin!.copyWithEdge(top: newInternalMargin); } } } @@ -840,7 +840,14 @@ class ContainerSpan extends StatelessWidget { @override Widget build(BuildContext _) { - return Container( + + // Elements that are inline should ignore margin: auto for alignment. + var alignment = shrinkWrap ? null : style.alignment; + if(style.display == Display.BLOCK) { + alignment = style.margin?.alignment ?? alignment; + } + + Widget container = Container( decoration: BoxDecoration( border: style.border, color: style.backgroundColor, @@ -848,8 +855,8 @@ class ContainerSpan extends StatelessWidget { height: style.height, width: style.width, padding: style.padding?.nonNegative, - margin: style.margin?.nonNegative, - alignment: shrinkWrap ? null : style.alignment, + margin: style.margin?.asInsets.nonNegative, + alignment: alignment, child: child ?? StyledText( textSpan: TextSpan( @@ -860,6 +867,8 @@ class ContainerSpan extends StatelessWidget { renderContext: newContext, ), ); + + return container; } } diff --git a/lib/src/css_parser.dart b/lib/src/css_parser.dart index 66c622a8cf..7551da7cd4 100644 --- a/lib/src/css_parser.dart +++ b/lib/src/css_parser.dart @@ -244,30 +244,31 @@ Style declarationsToStyle(Map> declarations) { && !(element is css.EmTerm) && !(element is css.RemTerm) && !(element is css.NumberTerm) + && !(element.text == 'auto') ); - List margin = ExpressionMapping.expressionToPadding(marginLengths); - style.margin = (style.margin ?? EdgeInsets.zero).copyWith( - left: margin[0], - right: margin[1], - top: margin[2], - bottom: margin[3], + Margins margin = ExpressionMapping.expressionToMargins(marginLengths); + style.margin = (style.margin ?? Margins.all(0)).copyWith( + left: margin.left, + right: margin.right, + top: margin.top, + bottom: margin.bottom, ); break; case 'margin-left': - style.margin = (style.margin ?? EdgeInsets.zero).copyWith( - left: ExpressionMapping.expressionToPaddingLength(value.first)); + style.margin = (style.margin ?? Margins.zero).copyWith( + left: ExpressionMapping.expressionToMargin(value.first)); break; case 'margin-right': - style.margin = (style.margin ?? EdgeInsets.zero).copyWith( - right: ExpressionMapping.expressionToPaddingLength(value.first)); + style.margin = (style.margin ?? Margins.zero).copyWith( + right: ExpressionMapping.expressionToMargin(value.first)); break; case 'margin-top': - style.margin = (style.margin ?? EdgeInsets.zero).copyWith( - top: ExpressionMapping.expressionToPaddingLength(value.first)); + style.margin = (style.margin ?? Margins.zero).copyWith( + top: ExpressionMapping.expressionToMargin(value.first)); break; case 'margin-bottom': - style.margin = (style.margin ?? EdgeInsets.zero).copyWith( - bottom: ExpressionMapping.expressionToPaddingLength(value.first)); + style.margin = (style.margin ?? Margins.zero).copyWith( + bottom: ExpressionMapping.expressionToMargin(value.first)); break; case 'padding': List? paddingLengths = value.whereType().toList(); @@ -748,6 +749,45 @@ class ExpressionMapping { return null; } + static Margin? expressionToMargin(css.Expression value) { + if ((value is css.LiteralTerm) && value.text == 'auto') { + return AutoMargin(); + } else { + return InsetMargin(expressionToPaddingLength(value) ?? 0); + } + } + + static Margins expressionToMargins(List? lengths) { + Margin? left; + Margin? right; + Margin? top; + Margin? bottom; + if (lengths != null && lengths.isNotEmpty) { + top = expressionToMargin(lengths.first); + if (lengths.length == 4) { + right = expressionToMargin(lengths[1]); + bottom = expressionToMargin(lengths[2]); + left = expressionToMargin(lengths.last); + } + if (lengths.length == 3) { + left = expressionToMargin(lengths[1]); + right = expressionToMargin(lengths[1]); + bottom = expressionToMargin(lengths.last); + } + if (lengths.length == 2) { + bottom = expressionToMargin(lengths.first); + left = expressionToMargin(lengths.last); + right = expressionToMargin(lengths.last); + } + if (lengths.length == 1) { + bottom = expressionToMargin(lengths.first); + left = expressionToMargin(lengths.first); + right = expressionToMargin(lengths.first); + } + } + return Margins(left: left, right: right, top: top, bottom: bottom); + } + static List expressionToPadding(List? lengths) { double? left; double? right; diff --git a/lib/src/styled_element.dart b/lib/src/styled_element.dart index 9561d8f228..9531f5bcf9 100644 --- a/lib/src/styled_element.dart +++ b/lib/src/styled_element.dart @@ -102,19 +102,19 @@ StyledElement parseStyledElement( //TODO(Sub6Resources) this is a workaround for collapsing margins. Remove. if (element.parent!.localName == "blockquote") { styledElement.style = Style( - margin: const EdgeInsets.only(left: 40.0, right: 40.0, bottom: 14.0), + margin: Margins.only(left: 40.0, right: 40.0, bottom: 14.0), display: Display.BLOCK, ); } else { styledElement.style = Style( - margin: const EdgeInsets.symmetric(horizontal: 40.0, vertical: 14.0), + margin: Margins.symmetric(horizontal: 40.0, vertical: 14.0), display: Display.BLOCK, ); } break; case "body": styledElement.style = Style( - margin: EdgeInsets.all(8.0), + margin: Margins.all(8.0), display: Display.BLOCK, ); break; @@ -134,7 +134,7 @@ StyledElement parseStyledElement( break; case "dd": styledElement.style = Style( - margin: EdgeInsets.only(left: 40.0), + margin: Margins.only(left: 40.0), display: Display.BLOCK, ); break; @@ -148,13 +148,13 @@ StyledElement parseStyledElement( continue italics; case "div": styledElement.style = Style( - margin: EdgeInsets.all(0), + margin: Margins.all(0), display: Display.BLOCK, ); break; case "dl": styledElement.style = Style( - margin: EdgeInsets.symmetric(vertical: 14.0), + margin: Margins.symmetric(vertical: 14.0), display: Display.BLOCK, ); break; @@ -172,7 +172,7 @@ StyledElement parseStyledElement( break; case "figure": styledElement.style = Style( - margin: EdgeInsets.symmetric(vertical: 14.0, horizontal: 40.0), + margin: Margins.symmetric(vertical: 14.0, horizontal: 40.0), display: Display.BLOCK, ); break; @@ -196,7 +196,7 @@ StyledElement parseStyledElement( styledElement.style = Style( fontSize: FontSize.xxLarge, fontWeight: FontWeight.bold, - margin: EdgeInsets.symmetric(vertical: 18.67), + margin: Margins.symmetric(vertical: 18.67), display: Display.BLOCK, ); break; @@ -204,7 +204,7 @@ StyledElement parseStyledElement( styledElement.style = Style( fontSize: FontSize.xLarge, fontWeight: FontWeight.bold, - margin: EdgeInsets.symmetric(vertical: 17.5), + margin: Margins.symmetric(vertical: 17.5), display: Display.BLOCK, ); break; @@ -212,7 +212,7 @@ StyledElement parseStyledElement( styledElement.style = Style( fontSize: FontSize(16.38), fontWeight: FontWeight.bold, - margin: EdgeInsets.symmetric(vertical: 16.5), + margin: Margins.symmetric(vertical: 16.5), display: Display.BLOCK, ); break; @@ -220,7 +220,7 @@ StyledElement parseStyledElement( styledElement.style = Style( fontSize: FontSize.medium, fontWeight: FontWeight.bold, - margin: EdgeInsets.symmetric(vertical: 18.5), + margin: Margins.symmetric(vertical: 18.5), display: Display.BLOCK, ); break; @@ -228,7 +228,7 @@ StyledElement parseStyledElement( styledElement.style = Style( fontSize: FontSize(11.62), fontWeight: FontWeight.bold, - margin: EdgeInsets.symmetric(vertical: 19.25), + margin: Margins.symmetric(vertical: 19.25), display: Display.BLOCK, ); break; @@ -236,7 +236,7 @@ StyledElement parseStyledElement( styledElement.style = Style( fontSize: FontSize(9.38), fontWeight: FontWeight.bold, - margin: EdgeInsets.symmetric(vertical: 22), + margin: Margins.symmetric(vertical: 22), display: Display.BLOCK, ); break; @@ -247,7 +247,7 @@ StyledElement parseStyledElement( break; case "hr": styledElement.style = Style( - margin: EdgeInsets.symmetric(vertical: 7.0), + margin: Margins.symmetric(vertical: 7.0), width: double.infinity, height: 1, backgroundColor: Colors.black, @@ -318,14 +318,14 @@ StyledElement parseStyledElement( break; case "p": styledElement.style = Style( - margin: EdgeInsets.symmetric(vertical: 14.0), + margin: Margins.symmetric(vertical: 14.0), display: Display.BLOCK, ); break; case "pre": styledElement.style = Style( fontFamily: 'monospace', - margin: EdgeInsets.symmetric(vertical: 14.0), + margin: Margins.symmetric(vertical: 14.0), whiteSpace: WhiteSpace.PRE, display: Display.BLOCK, ); diff --git a/lib/style.dart b/lib/style.dart index fc2c3f6d21..3ac2ff7ba8 100644 --- a/lib/style.dart +++ b/lib/style.dart @@ -95,7 +95,7 @@ class Style { /// /// Inherited: no, /// Default: EdgeInsets.zero - EdgeInsets? margin; + Margins? margin; /// CSS attribute "`text-align`" /// @@ -378,7 +378,7 @@ class Style { ListStyleType? listStyleType, ListStylePosition? listStylePosition, EdgeInsets? padding, - EdgeInsets? margin, + Margins? margin, TextAlign? textAlign, TextDecoration? textDecoration, Color? textDecorationColor, @@ -466,6 +466,97 @@ enum Display { NONE, } +abstract class Margin { + const Margin(); + + double get value => this is InsetMargin ? this.value : 0; + } + +class AutoMargin extends Margin { + const AutoMargin(); +} + +class InsetMargin extends Margin { + final double value; + const InsetMargin(this.value); +} + +class Margins { + final Margin? left; + final Margin? right; + final Margin? top; + final Margin? bottom; + + const Margins({ this.left, this.right, this.top, this.bottom }); + + /// Auto margins already have a "value" of zero so can be considered collapsed. + Margins collapse() => Margins( + left: left is AutoMargin ? left : InsetMargin(0), + right: right is AutoMargin ? right : InsetMargin(0), + top: top is AutoMargin ? top : InsetMargin(0), + bottom: bottom is AutoMargin ? bottom : InsetMargin(0), + ); + + Margins copyWith({ Margin? left, Margin? right, Margin? top, Margin? bottom }) => Margins( + left: left ?? this.left, + right: right ?? this.right, + top: top ?? this.top, + bottom: bottom ?? this.bottom, + ); + + Margins copyWithEdge({ double? left, double? right, double? top, double? bottom }) => Margins( + left: left != null ? InsetMargin(left) : this.left, + right: right != null ? InsetMargin(right) : this.right, + top: top != null ? InsetMargin(top) : this.top, + bottom: bottom != null ? InsetMargin(bottom) : this.bottom, + ); + + bool get isAutoHorizontal => (left is AutoMargin) || (right is AutoMargin); + + Alignment? get alignment { + if((left is AutoMargin) && (right is AutoMargin)) { + return Alignment.center; + } else if(left is AutoMargin) { + return Alignment.topRight; + } + } + + /// Analogous to [EdgeInsets.zero] + static Margins get zero => Margins.all(0); + + /// Analogous to [EdgeInsets.all] + static Margins all(double value) => Margins( + left: InsetMargin(value), + right: InsetMargin(value), + top: InsetMargin(value), + bottom: InsetMargin(value), + ); + + /// Analogous to [EdgeInsets.only] + static Margins only({ double? left, double? right, double? top, double? bottom }) => Margins( + left: InsetMargin(left ?? 0), + right: InsetMargin(right ?? 0), + top: InsetMargin(top ?? 0), + bottom: InsetMargin(bottom ?? 0), + ); + + + /// Analogous to [EdgeInsets.symmetric] + static Margins symmetric({double? horizontal, double? vertical}) => Margins( + left: InsetMargin(horizontal ?? 0), + right: InsetMargin(horizontal ?? 0), + top: InsetMargin(vertical ?? 0), + bottom: InsetMargin(vertical ?? 0), + ); + + EdgeInsets get asInsets => EdgeInsets.zero.copyWith( + left: left?.value ?? 0, + right: right?.value ?? 0, + top: top?.value ?? 0, + bottom: bottom?.value ?? 0, + ); +} + class FontSize { final double? size; final String units; diff --git a/packages/flutter_html_table/lib/flutter_html_table.dart b/packages/flutter_html_table/lib/flutter_html_table.dart index 7791f36f2c..7a48613fc0 100644 --- a/packages/flutter_html_table/lib/flutter_html_table.dart +++ b/packages/flutter_html_table/lib/flutter_html_table.dart @@ -9,7 +9,7 @@ import 'package:flutter_html/flutter_html.dart'; CustomRender tableRender() => CustomRender.widget(widget: (context, buildChildren) { return Container( key: context.key, - margin: context.style.margin?.nonNegative, + margin: context.style.margin?.asInsets.nonNegative, padding: context.style.padding?.nonNegative, alignment: context.style.alignment, decoration: BoxDecoration( From 1c2412a24374c704af3ed39e0c21a0404b7925c3 Mon Sep 17 00:00:00 2001 From: wangbax Date: Mon, 28 Mar 2022 21:31:02 +0800 Subject: [PATCH 002/111] fix: ol use default style --- lib/custom_render.dart | 2 +- lib/html_parser.dart | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/lib/custom_render.dart b/lib/custom_render.dart index 9b4abd8890..1115c3ae78 100644 --- a/lib/custom_render.dart +++ b/lib/custom_render.dart @@ -173,7 +173,7 @@ CustomRender listElementRender({ right: (style?.direction ?? context.tree.style.direction) == TextDirection.rtl ? 10.0 : 0.0), child: style?.markerContent ?? context.style.markerContent ) : Container(height: 0, width: 0), - Text("\t", textAlign: TextAlign.right, style: TextStyle(fontWeight: FontWeight.w400)), + Text("\u0020", textAlign: TextAlign.right, style: TextStyle(fontWeight: FontWeight.w400)), Expanded( child: Padding( padding: (style?.listStylePosition ?? context.tree.style.listStylePosition) == ListStylePosition.INSIDE ? diff --git a/lib/html_parser.dart b/lib/html_parser.dart index 4f15b9a8a1..226f4223c4 100644 --- a/lib/html_parser.dart +++ b/lib/html_parser.dart @@ -606,6 +606,7 @@ class HtmlParser extends StatelessWidget { tree.style.markerContent = Text( marker, textAlign: TextAlign.right, + style: tree.style.generateTextStyle(), ); } From 283c3afa8222687e0cdc3c1657be36c68e8dd944 Mon Sep 17 00:00:00 2001 From: Eric Kok Date: Thu, 14 Apr 2022 13:51:00 +0200 Subject: [PATCH 003/111] Don't crash when video ir iframe uses unsupported height/width; fixes #1033 --- .../lib/iframe_mobile.dart | 8 ++--- .../flutter_html_iframe/lib/iframe_web.dart | 8 ++--- .../lib/flutter_html_video.dart | 30 +++++++++---------- 3 files changed, 22 insertions(+), 24 deletions(-) diff --git a/packages/flutter_html_iframe/lib/iframe_mobile.dart b/packages/flutter_html_iframe/lib/iframe_mobile.dart index 2bd5b4608c..a75a98362c 100644 --- a/packages/flutter_html_iframe/lib/iframe_mobile.dart +++ b/packages/flutter_html_iframe/lib/iframe_mobile.dart @@ -7,11 +7,11 @@ import 'package:webview_flutter/webview_flutter.dart'; CustomRender iframeRender({NavigationDelegate? navigationDelegate}) => CustomRender.widget(widget: (context, buildChildren) { final sandboxMode = context.tree.element?.attributes["sandbox"]; final UniqueKey key = UniqueKey(); + final givenWidth = double.tryParse(context.tree.element?.attributes['width'] ?? ""); + final givenHeight = double.tryParse(context.tree.element?.attributes['height'] ?? ""); return Container( - width: double.tryParse(context.tree.element?.attributes['width'] ?? "") - ?? (double.tryParse(context.tree.element?.attributes['height'] ?? "") ?? 150) * 2, - height: double.tryParse(context.tree.element?.attributes['height'] ?? "") - ?? (double.tryParse(context.tree.element?.attributes['width'] ?? "") ?? 300) / 2, + width: givenWidth ?? (givenHeight ?? 150) * 2, + height: givenHeight ?? (givenWidth ?? 300) / 2, child: ContainerSpan( style: context.style, newContext: context, diff --git a/packages/flutter_html_iframe/lib/iframe_web.dart b/packages/flutter_html_iframe/lib/iframe_web.dart index 1e9c50598f..4b09ec7a6c 100644 --- a/packages/flutter_html_iframe/lib/iframe_web.dart +++ b/packages/flutter_html_iframe/lib/iframe_web.dart @@ -10,11 +10,11 @@ import 'dart:html' as html; import 'package:webview_flutter/webview_flutter.dart'; CustomRender iframeRender({NavigationDelegate? navigationDelegate}) => CustomRender.widget(widget: (context, buildChildren) { + final givenWidth = double.tryParse(context.tree.element?.attributes['width'] ?? ""); + final givenHeight = double.tryParse(context.tree.element?.attributes['height'] ?? ""); final html.IFrameElement iframe = html.IFrameElement() - ..width = (double.tryParse(context.tree.element?.attributes['width'] ?? "") - ?? (double.tryParse(context.tree.element?.attributes['height'] ?? "") ?? 150) * 2).toString() - ..height = (double.tryParse(context.tree.element?.attributes['height'] ?? "") - ?? (double.tryParse(context.tree.element?.attributes['width'] ?? "") ?? 300) / 2).toString() + ..width = (givenWidth ?? (givenHeight ?? 150) * 2).toString() + ..height = (givenHeight ?? (givenWidth ?? 300) / 2).toString() ..src = context.tree.element?.attributes['src'] ..style.border = 'none'; final String createdViewId = getRandString(10); diff --git a/packages/flutter_html_video/lib/flutter_html_video.dart b/packages/flutter_html_video/lib/flutter_html_video.dart index 90591d5c55..78ccfe8936 100644 --- a/packages/flutter_html_video/lib/flutter_html_video.dart +++ b/packages/flutter_html_video/lib/flutter_html_video.dart @@ -30,11 +30,10 @@ class VideoWidget extends StatefulWidget { } class _VideoWidgetState extends State { - ChewieController? chewieController; - VideoPlayerController? videoController; + ChewieController? _chewieController; + VideoPlayerController? _videoController; double? _width; double? _height; - late final List sources; @override void initState() { @@ -44,12 +43,14 @@ class _VideoWidgetState extends State { attributes['src'], ...ReplacedElement.parseMediaSources(widget.context.tree.element!.children), ]; + final givenWidth = double.tryParse(attributes['width'] ?? ""); + final givenHeight = double.tryParse(attributes['height'] ?? ""); if (sources.isNotEmpty && sources.first != null) { - _width = double.tryParse(attributes['width'] ?? (attributes['height'] ?? 150) * 2); - _height = double.tryParse(attributes['height'] ?? (attributes['width'] ?? 300) / 2); - videoController = VideoPlayerController.network(sources.first!); - chewieController = ChewieController( - videoPlayerController: videoController!, + _width = givenWidth ?? (givenHeight ?? 150) * 2; + _height = givenHeight ?? (givenWidth ?? 300) / 2; + _videoController = VideoPlayerController.network(sources.first!); + _chewieController = ChewieController( + videoPlayerController: _videoController!, placeholder: attributes['poster'] != null && attributes['poster']!.isNotEmpty ? Image.network(attributes['poster']!) : Container(color: Colors.black), @@ -59,32 +60,29 @@ class _VideoWidgetState extends State { autoInitialize: true, aspectRatio: _width == null || _height == null ? null : _width! / _height!, ); - widget.callback?.call(widget.context.tree.element, chewieController!, videoController!); + widget.callback?.call(widget.context.tree.element, _chewieController!, _videoController!); } super.initState(); } @override void dispose() { - chewieController?.dispose(); - videoController?.dispose(); + _chewieController?.dispose(); + _videoController?.dispose(); super.dispose(); } @override Widget build(BuildContext bContext) { - if (sources.isEmpty || sources.first == null) { + if (_chewieController == null) { return Container(height: 0, width: 0); } final child = Container( key: widget.context.key, child: Chewie( - controller: chewieController!, + controller: _chewieController!, ), ); - if (_width == null || _height == null) { - return child; - } return AspectRatio( aspectRatio: _width! / _height!, child: child, From ec3ac1cf8f04e9b2d8e43c6646740f9836d445df Mon Sep 17 00:00:00 2001 From: Eric Kok Date: Thu, 14 Apr 2022 14:07:17 +0200 Subject: [PATCH 004/111] 3.0.0-alpha.3 release --- CHANGELOG.md | 4 ++++ README.md | 2 +- packages/flutter_html_all/pubspec.yaml | 16 ++++++++-------- packages/flutter_html_audio/pubspec.yaml | 4 ++-- packages/flutter_html_iframe/CHANGELOG.md | 3 +++ packages/flutter_html_iframe/pubspec.yaml | 4 ++-- packages/flutter_html_math/pubspec.yaml | 4 ++-- packages/flutter_html_svg/pubspec.yaml | 4 ++-- packages/flutter_html_table/pubspec.yaml | 4 ++-- packages/flutter_html_video/CHANGELOG.md | 3 +++ packages/flutter_html_video/pubspec.yaml | 4 ++-- pubspec.yaml | 2 +- 12 files changed, 32 insertions(+), 22 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5879aafab7..78ad789752 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,7 @@ +## [3.0.0-alpha.3] - April 14, 2022: +* Fixed styling not being applied to list item markers +* [video] Fixed crash when iframe or video tags used unsupported/incorrect height or width + ## [3.0.0-alpha.2] - January 5, 2022: * **BREAKING** Full modularization using split packages; see our upgrade guide or use flutter_html_all diff --git a/README.md b/README.md index 326ac6ccb7..d7aacfe45e 100644 --- a/README.md +++ b/README.md @@ -90,7 +90,7 @@ A Flutter widget for rendering HTML and CSS as Flutter widgets. Add the following to your `pubspec.yaml` file: dependencies: - flutter_html: ^3.0.0-alpha.2 + flutter_html: ^3.0.0-alpha.3 ## Currently Supported HTML Tags: | | | | | | | | | | | | diff --git a/packages/flutter_html_all/pubspec.yaml b/packages/flutter_html_all/pubspec.yaml index 9bea10a832..7f5b9305de 100644 --- a/packages/flutter_html_all/pubspec.yaml +++ b/packages/flutter_html_all/pubspec.yaml @@ -1,6 +1,6 @@ name: flutter_html_all description: All optional flutter_html widgets, bundled into a single package. -version: 3.0.0-alpha.2 +version: 3.0.0-alpha.3 homepage: https://github.com/Sub6Resources/flutter_html environment: @@ -11,13 +11,13 @@ dependencies: flutter: sdk: flutter html: '>=0.15.0 <1.0.0' - flutter_html: '>=3.0.0-alpha.2 <4.0.0' - flutter_html_audio: '>=3.0.0-alpha.2 <4.0.0' - flutter_html_iframe: '>=3.0.0-alpha.2 <4.0.0' - flutter_html_math: '>=3.0.0-alpha.2 <4.0.0' - flutter_html_svg: '>=3.0.0-alpha.2 <4.0.0' - flutter_html_table: '>=3.0.0-alpha.2 <4.0.0' - flutter_html_video: '>=3.0.0-alpha.2 <4.0.0' + flutter_html: '>=3.0.0-alpha.3 <4.0.0' + flutter_html_audio: '>=3.0.0-alpha.3 <4.0.0' + flutter_html_iframe: '>=3.0.0-alpha.3 <4.0.0' + flutter_html_math: '>=3.0.0-alpha.3 <4.0.0' + flutter_html_svg: '>=3.0.0-alpha.3 <4.0.0' + flutter_html_table: '>=3.0.0-alpha.3 <4.0.0' + flutter_html_video: '>=3.0.0-alpha.3 <4.0.0' # flutter_html_audio: # path: ../flutter_html_audio # flutter_html_iframe: diff --git a/packages/flutter_html_audio/pubspec.yaml b/packages/flutter_html_audio/pubspec.yaml index 16076e952b..adcd592e80 100644 --- a/packages/flutter_html_audio/pubspec.yaml +++ b/packages/flutter_html_audio/pubspec.yaml @@ -1,6 +1,6 @@ name: flutter_html_audio description: Audio widget for flutter_html. -version: 3.0.0-alpha.2 +version: 3.0.0-alpha.3 homepage: https://github.com/Sub6Resources/flutter_html environment: @@ -11,7 +11,7 @@ dependencies: flutter: sdk: flutter html: '>=0.15.0 <1.0.0' - flutter_html: '>=3.0.0-alpha.2 <4.0.0' + flutter_html: '>=3.0.0-alpha.3 <4.0.0' # flutter_html: # path: ../.. diff --git a/packages/flutter_html_iframe/CHANGELOG.md b/packages/flutter_html_iframe/CHANGELOG.md index 31b4275bb4..7c233e36a8 100644 --- a/packages/flutter_html_iframe/CHANGELOG.md +++ b/packages/flutter_html_iframe/CHANGELOG.md @@ -1,2 +1,5 @@ +## [3.0.0-alpha.3] - April 14, 2022: +* Fixed crash when iframe or video tags used unsupported/incorrect height or width + ## [3.0.0-alpha.2] - January 5, 2022: * Initial modularized flutter_html release; use flutter_html_iframe if you need support for the `