Skip to content

Commit 056a9b3

Browse files
committed
Fix nits and other minor code issues
1 parent bc1ed9d commit 056a9b3

File tree

3 files changed

+29
-41
lines changed

3 files changed

+29
-41
lines changed

README.md

Lines changed: 5 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -161,15 +161,11 @@ The difference between the two is the same as noted above.
161161

162162
Please note: Due to Flutter [#38474](https://github.com/flutter/flutter/issues/38474), selectable text support is significantly watered down compared to the standard non-selectable version of the widget. The changes are as follows:
163163

164-
1. No support for `customRender`, `customImageRender`, `onImageError`, `onImageTap`, `onMathError`, and `navigationDelegateForIframe`. (Support for `customRender` may be added in the future).
164+
1. The list of tags that can be rendered is significantly reduced. Key omissions include no support for images/video/audio, table, and ul/ol.
165165

166-
2. You cannot whitelist tags, you must use `blacklistedElements` to remove any tags that shouldn't be rendered. This is to make sure unsupported tags are not accidentally whitelisted, causing errors in the widget code.
166+
2. No support for `customRender`, `customImageRender`, `onImageError`, `onImageTap`, `onMathError`, and `navigationDelegateForIframe`. (Support for `customRender` may be added in the future).
167167

168-
3. The list of tags that can be rendered is significantly reduced. Key omissions include no support for images/video/audio, table, and ul/ol.
169-
170-
4. Styling support is significantly reduced. Only text-related styling works (e.g. bold or italic), while container related styling (e.g. borders or padding/margin) do not work.
171-
172-
5. Due to the above, the margins between elements no longer appear. As a result, the HTML content will not have proper spacing between elements like `<h1>`. The default margin for `<body>` is removed, so it is recommended to wrap the `Html()` widget in a `Container()` with padding to achieve the same effect.
168+
3. Styling support is significantly reduced. Only text-related styling works (e.g. bold or italic), while container related styling (e.g. borders or padding/margin) do not work.
173169

174170
Once the above issue is resolved, the aforementioned compromises will go away. Currently the `SelectableText.rich()` constructor does not support `WidgetSpan`s, resulting in the feature losses above.
175171

@@ -192,7 +188,7 @@ Once the above issue is resolved, the aforementioned compromises will go away. C
192188

193189
### Getters:
194190

195-
1. `Html.tags`. This provides a list of all the tags the package renders. The main use case is to assist in blacklisting elements using `tagsList`. See an [example](#example-usage---tagslist---excluding-tags) below.
191+
1. `Html.tags`. This provides a list of all the tags the package renders. The main use case is to assist in excluding elements using `tagsList`. See an [example](#example-usage---tagslist---excluding-tags) below.
196192

197193
2. `SelectableHtml.tags`. This provides a list of all the tags that can be rendered in selectable mode.
198194

@@ -440,7 +436,7 @@ A list of elements the `Html` widget should render. The list should contain the
440436
#### Example Usage - tagsList - Excluding Tags:
441437
You may have instances where you can choose between two different types of HTML tags to display the same content. In the example below, the `<video>` and `<iframe>` elements are going to display the same content.
442438

443-
The `blacklistedElements` parameter allows you to change which element is rendered. Iframes can be advantageous because they allow parallel loading - Flutter just has to wait for the webview to be initialized before rendering the page, possibly cutting down on load time. Video can be advantageous because it provides a 100% native experience with Flutter widgets, but it may take more time to render the page. You may know that Flutter webview is a little janky in its current state on Android, so using `blacklistedElements` and a simple condition, you can get the best of both worlds - choose the video widget to render on Android and the iframe webview to render on iOS.
439+
The `tagsList` parameter allows you to change which element is rendered. Iframes can be advantageous because they allow parallel loading - Flutter just has to wait for the webview to be initialized before rendering the page, possibly cutting down on load time. Video can be advantageous because it provides a 100% native experience with Flutter widgets, but it may take more time to render the page. You may know that Flutter webview is a little janky in its current state on Android, so using `tagsList` and a simple condition, you can get the best of both worlds - choose the video widget to render on Android and the iframe webview to render on iOS.
444440

445441
```dart
446442
Widget html = Html(

lib/flutter_html.dart

Lines changed: 10 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -180,7 +180,7 @@ class SelectableHtml extends StatelessWidget {
180180
/// **onLinkTap** This function is called whenever a link (`<a href>`)
181181
/// is tapped.
182182
///
183-
/// **blacklistedElements** Tag names in this array will not be rendered.
183+
/// **tagsList** Tag names in this array will be the only tags rendered. By default all tags that support selectable content are rendered.
184184
///
185185
/// **style** Pass in the style information for the Html here.
186186
/// See [its wiki page](https://github.com/Sub6Resources/flutter_html/wiki/Style) for more info.
@@ -189,28 +189,23 @@ class SelectableHtml extends StatelessWidget {
189189
///
190190
/// There are a few caveats due to Flutter [#38474](https://github.com/flutter/flutter/issues/38474):
191191
///
192-
/// 1. No support for `customRender`, `customImageRender`, `onImageError`, `onImageTap`, `onMathError`, and `navigationDelegateForIframe`.
193-
///
194-
/// 2. You cannot whitelist tags, you must use `blacklistedElements` to remove any tags that shouldn't be rendered.
195-
/// This is to make sure unsupported tags are not accidentally whitelisted, causing errors in the widget code.
196-
///
197-
/// 3. The list of tags that can be rendered is significantly reduced.
192+
/// 1. The list of tags that can be rendered is significantly reduced.
198193
/// Key omissions include no support for images/video/audio, table, and ul/ol because they all require widgets and `WidgetSpan`s.
199194
///
200-
/// 4. Styling support is significantly reduced. Only text-related styling works
195+
/// 2. No support for `customRender`, `customImageRender`, `onImageError`, `onImageTap`, `onMathError`, and `navigationDelegateForIframe`.
196+
///
197+
/// 3. Styling support is significantly reduced. Only text-related styling works
201198
/// (e.g. bold or italic), while container related styling (e.g. borders or padding/margin)
202199
/// do not work because we can't use the `ContainerSpan` class (it needs an enclosing `WidgetSpan`).
203-
///
204-
/// 5. Due to the above, the margins between elements no longer appear.
205-
/// As a result, the HTML content will not have proper spacing between elements like `h1`. The default margin for `body` is removed as well.
200+
206201
SelectableHtml({
207202
Key? key,
208203
required this.data,
209204
this.onLinkTap,
210205
this.onCssParseError,
211206
this.shrinkWrap = false,
212207
this.style = const {},
213-
this.blacklistedElements = const [],
208+
this.tagsList = const [],
214209
}) : document = null,
215210
super(key: key);
216211

@@ -221,7 +216,7 @@ class SelectableHtml extends StatelessWidget {
221216
this.onCssParseError,
222217
this.shrinkWrap = false,
223218
this.style = const {},
224-
this.blacklistedElements = const [],
219+
this.tagsList = const [],
225220
}) : data = null,
226221
super(key: key);
227222

@@ -242,7 +237,7 @@ class SelectableHtml extends StatelessWidget {
242237
final bool shrinkWrap;
243238

244239
/// A list of HTML tags that defines what elements are not rendered
245-
final List<String> blacklistedElements;
240+
final List<String> tagsList;
246241

247242
/// An API that allows you to override the default style for any HTML element
248243
final Map<String, Style> style;
@@ -270,7 +265,7 @@ class SelectableHtml extends StatelessWidget {
270265
customRender: {},
271266
imageRenders: {}
272267
..addAll(defaultImageRenders),
273-
tagsList: SelectableHtml.tags..removeWhere((element) => (blacklistedElements).contains(element)),
268+
tagsList: tagsList.isEmpty ? SelectableHtml.tags : tagsList,
274269
navigationDelegateForIframe: null,
275270
),
276271
);

lib/html_parser.dart

Lines changed: 14 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -304,7 +304,7 @@ class HtmlParser extends StatelessWidget {
304304
tree: tree,
305305
style: context.style.copyOnlyInherited(tree.style),
306306
);
307-
List<int> indices = [];
307+
List<int> lineEndingIndices = [];
308308
tree.children.forEachIndexed((index, element) {
309309
//we want the element to be a block element, but we don't want to add
310310
//new-lines before/after the html and body
@@ -315,17 +315,17 @@ class HtmlParser extends StatelessWidget {
315315
//if the parent element is body and the element is first, we don't want
316316
//to add a new-line before
317317
if (index == 0 && element.element?.parent?.localName == "body") {
318-
indices.add(index + 1);
318+
lineEndingIndices.add(index + 1);
319319
} else {
320-
indices.addAll([index, index + 1]);
320+
lineEndingIndices.addAll([index, index + 1]);
321321
}
322322
}
323323
});
324324
//we don't need a new-line at the end
325-
if (indices.isNotEmpty && indices.last == tree.children.length) {
326-
indices.removeLast();
325+
if (lineEndingIndices.isNotEmpty && lineEndingIndices.last == tree.children.length) {
326+
lineEndingIndices.removeLast();
327327
}
328-
indices = indices.toSet().toList();
328+
lineEndingIndices = lineEndingIndices.toSet().toList();
329329
if (customRender.containsKey(tree.name)) {
330330
final render = customRender[tree.name]!.call(
331331
newContext,
@@ -359,7 +359,7 @@ class HtmlParser extends StatelessWidget {
359359
final children = tree.children.map((tree) => parseTree(newContext, tree)).toList();
360360
//use provided indices to insert new-lines at those locations
361361
//makes sure to account for list size changes with "+ i"
362-
indices.forEachIndexed((i, element) {
362+
lineEndingIndices.forEachIndexed((i, element) {
363363
children.insert(element + i, TextSpan(text: "\n"));
364364
});
365365
return TextSpan(
@@ -927,16 +927,13 @@ class StyledText extends StatelessWidget {
927927
@override
928928
Widget build(BuildContext context) {
929929
if (_selectable) {
930-
return SizedBox(
931-
width: calculateWidth(style.display, renderContext),
932-
child: SelectableText.rich(
933-
textSpan as TextSpan,
934-
style: style.generateTextStyle(),
935-
textAlign: style.textAlign,
936-
textDirection: style.direction,
937-
textScaleFactor: textScaleFactor,
938-
maxLines: style.maxLines,
939-
),
930+
return SelectableText.rich(
931+
textSpan as TextSpan,
932+
style: style.generateTextStyle(),
933+
textAlign: style.textAlign,
934+
textDirection: style.direction,
935+
textScaleFactor: textScaleFactor,
936+
maxLines: style.maxLines,
940937
);
941938
}
942939
return SizedBox(

0 commit comments

Comments
 (0)