From 8a350ccb84a9c714f12b7caa47ed7f73f6f379a8 Mon Sep 17 00:00:00 2001 From: Andy Date: Sat, 4 Sep 2021 21:43:25 +0700 Subject: [PATCH 1/3] change DOM Document to Element for more flexible --- lib/flutter_html.dart | 67 +++++++++++++++++++++---------------------- lib/html_parser.dart | 12 ++++---- 2 files changed, 39 insertions(+), 40 deletions(-) diff --git a/lib/flutter_html.dart b/lib/flutter_html.dart index d0a68217ef..7d383811ca 100644 --- a/lib/flutter_html.dart +++ b/lib/flutter_html.dart @@ -12,12 +12,14 @@ import 'package:webview_flutter/webview_flutter.dart'; //export render context api export 'package:flutter_html/html_parser.dart'; export 'package:flutter_html/image_render.dart'; + //export src for advanced custom render uses (e.g. casting context.tree) export 'package:flutter_html/src/anchor.dart'; export 'package:flutter_html/src/interactable_element.dart'; export 'package:flutter_html/src/layout_element.dart'; export 'package:flutter_html/src/replaced_element.dart'; export 'package:flutter_html/src/styled_element.dart'; + //export style api export 'package:flutter_html/style.dart'; @@ -95,8 +97,8 @@ class Html extends StatelessWidget { /// The HTML data passed to the widget as a String final String? data; - /// The HTML data passed to the widget as a pre-processed [dom.Document] - final dom.Document? document; + /// The HTML data passed to the widget as a pre-processed [dom.Element] + final dom.Element? document; /// A function that defines what to do when a link is tapped final OnTap? onLinkTap; @@ -150,8 +152,7 @@ class Html extends StatelessWidget { @override Widget build(BuildContext context) { - final dom.Document doc = - data != null ? HtmlParser.parseHTML(data!) : document!; + final dom.Element doc = data != null ? HtmlParser.parseHTML(data!): document!; final double? width = shrinkWrap ? null : MediaQuery.of(context).size.width; return Container( @@ -169,9 +170,7 @@ class Html extends StatelessWidget { selectable: false, style: style, customRender: customRender, - imageRenders: {} - ..addAll(customImageRenders) - ..addAll(defaultImageRenders), + imageRenders: {}..addAll(customImageRenders)..addAll(defaultImageRenders), tagsList: tagsList.isEmpty ? Html.tags : tagsList, navigationDelegateForIframe: navigationDelegateForIframe, ), @@ -211,34 +210,34 @@ class SelectableHtml extends StatelessWidget { /// (e.g. bold or italic), while container related styling (e.g. borders or padding/margin) /// do not work because we can't use the `ContainerSpan` class (it needs an enclosing `WidgetSpan`). - SelectableHtml({ - Key? key, - GlobalKey? anchorKey, - required this.data, - this.onLinkTap, - this.onAnchorTap, - this.onCssParseError, - this.shrinkWrap = false, - this.style = const {}, - this.tagsList = const [], - this.selectionControls - }) : document = null, + SelectableHtml( + {Key? key, + GlobalKey? anchorKey, + required this.data, + this.onLinkTap, + this.onAnchorTap, + this.onCssParseError, + this.shrinkWrap = false, + this.style = const {}, + this.tagsList = const [], + this.selectionControls}) + : document = null, assert(data != null), _anchorKey = anchorKey ?? GlobalKey(), super(key: key); - SelectableHtml.fromDom({ - Key? key, - GlobalKey? anchorKey, - required this.document, - this.onLinkTap, - this.onAnchorTap, - this.onCssParseError, - this.shrinkWrap = false, - this.style = const {}, - this.tagsList = const [], - this.selectionControls - }) : data = null, + SelectableHtml.fromDom( + {Key? key, + GlobalKey? anchorKey, + required this.document, + this.onLinkTap, + this.onAnchorTap, + this.onCssParseError, + this.shrinkWrap = false, + this.style = const {}, + this.tagsList = const [], + this.selectionControls}) + : data = null, assert(document != null), _anchorKey = anchorKey ?? GlobalKey(), super(key: key); @@ -249,8 +248,8 @@ class SelectableHtml extends StatelessWidget { /// The HTML data passed to the widget as a String final String? data; - /// The HTML data passed to the widget as a pre-processed [dom.Document] - final dom.Document? document; + /// The HTML data passed to the widget as a pre-processed [dom.Element] + final dom.Element? document; /// A function that defines what to do when a link is tapped final OnTap? onLinkTap; @@ -280,7 +279,7 @@ class SelectableHtml extends StatelessWidget { @override Widget build(BuildContext context) { - final dom.Document doc = data != null ? HtmlParser.parseHTML(data!) : document!; + final dom.Element doc = data != null ? HtmlParser.parseHTML(data!) : document!; final double? width = shrinkWrap ? null : MediaQuery.of(context).size.width; return Container( diff --git a/lib/html_parser.dart b/lib/html_parser.dart index 9818157fd2..d991991f94 100644 --- a/lib/html_parser.dart +++ b/lib/html_parser.dart @@ -42,7 +42,7 @@ typedef CustomRender = dynamic Function( class HtmlParser extends StatelessWidget { final Key? key; - final dom.Document htmlData; + final dom.Element htmlData; final OnTap? onLinkTap; final OnTap? onAnchorTap; final OnTap? onImageTap; @@ -143,9 +143,9 @@ class HtmlParser extends StatelessWidget { ); } - /// [parseHTML] converts a string of HTML to a DOM document using the dart `html` library. - static dom.Document parseHTML(String data) { - return htmlparser.parse(data); + /// [parseHTML] converts a string of HTML to a DOM element using the dart `html` library. + static dom.Element parseHTML(String data) { + return htmlparser.parse(data).documentElement!; } /// [parseCss] converts a string of CSS to a CSS stylesheet using the dart `csslib` library. @@ -155,7 +155,7 @@ class HtmlParser extends StatelessWidget { /// [lexDomTree] converts a DOM document to a simplified tree of [StyledElement]s. static StyledElement lexDomTree( - dom.Document html, + dom.Element html, List customRenderTags, List tagsList, NavigationDelegate? navigationDelegateForIframe, @@ -164,7 +164,7 @@ class HtmlParser extends StatelessWidget { StyledElement tree = StyledElement( name: "[Tree Root]", children: [], - node: html.documentElement, + node: html, style: Style.fromTextStyle(Theme.of(context).textTheme.bodyText2!), ); From d972f6d3e28d840262f3d223c6da408f47e4e4b3 Mon Sep 17 00:00:00 2001 From: Andy Date: Sat, 8 Jan 2022 15:46:54 +0700 Subject: [PATCH 2/3] add fromElement constructor --- lib/flutter_html.dart | 24 +++++++++++++++++++++++- 1 file changed, 23 insertions(+), 1 deletion(-) diff --git a/lib/flutter_html.dart b/lib/flutter_html.dart index 7d383811ca..b42452e214 100644 --- a/lib/flutter_html.dart +++ b/lib/flutter_html.dart @@ -73,7 +73,29 @@ class Html extends StatelessWidget { Html.fromDom({ Key? key, GlobalKey? anchorKey, - @required this.document, + @required dom.Document? document, + this.onLinkTap, + this.onAnchorTap, + this.customRender = const {}, + this.customImageRenders = const {}, + this.onCssParseError, + this.onImageError, + this.onMathError, + this.shrinkWrap = false, + this.onImageTap, + this.tagsList = const [], + this.style = const {}, + this.navigationDelegateForIframe, + }) : data = null, + assert(document != null), + this.document = document!.documentElement, + _anchorKey = anchorKey ?? GlobalKey(), + super(key: key); + + Html.fromElement({ + Key? key, + GlobalKey? anchorKey, + this.document, this.onLinkTap, this.onAnchorTap, this.customRender = const {}, From 0e83da06e3dc54c2b0ddb9bde1a9381b63969d6f Mon Sep 17 00:00:00 2001 From: Andy Date: Sat, 8 Jan 2022 15:48:56 +0700 Subject: [PATCH 3/3] add fromElement constructor --- lib/flutter_html.dart | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/lib/flutter_html.dart b/lib/flutter_html.dart index b42452e214..ba4bc2a5f7 100644 --- a/lib/flutter_html.dart +++ b/lib/flutter_html.dart @@ -95,7 +95,7 @@ class Html extends StatelessWidget { Html.fromElement({ Key? key, GlobalKey? anchorKey, - this.document, + @required this.document, this.onLinkTap, this.onAnchorTap, this.customRender = const {}, @@ -174,7 +174,7 @@ class Html extends StatelessWidget { @override Widget build(BuildContext context) { - final dom.Element doc = data != null ? HtmlParser.parseHTML(data!): document!; + final dom.Element doc = data != null ? HtmlParser.parseHTML(data!) : document!; final double? width = shrinkWrap ? null : MediaQuery.of(context).size.width; return Container( @@ -192,7 +192,9 @@ class Html extends StatelessWidget { selectable: false, style: style, customRender: customRender, - imageRenders: {}..addAll(customImageRenders)..addAll(defaultImageRenders), + imageRenders: {} + ..addAll(customImageRenders) + ..addAll(defaultImageRenders), tagsList: tagsList.isEmpty ? Html.tags : tagsList, navigationDelegateForIframe: navigationDelegateForIframe, ),