Skip to content

Commit 0a201ce

Browse files
committed
Merge changes and fix minor bug with asset SVG
1 parent ac5d36f commit 0a201ce

File tree

3 files changed

+28
-47
lines changed

3 files changed

+28
-47
lines changed

README.md

Lines changed: 22 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -148,7 +148,7 @@ If you would like to modify or sanitize the HTML before rendering it, then `Html
148148
| `data` | The HTML data passed to the `Html` widget. This is required and cannot be null when using `Html()`. |
149149
| `document` | The DOM document passed to the `Html` widget. This is required and cannot be null when using `Html.fromDom()`. |
150150
| `onLinkTap` | A function that defines what the widget should do when a link is tapped. The function exposes the `src` of the link as a `String` to use in your implementation. |
151-
| `customRender` | A powerful API that allows you to customize everything when rendering a specific HTML tag. |
151+
| `customRenders` | A powerful API that allows you to customize everything when rendering a specific HTML tag. |
152152
| `onImageError` | A function that defines what the widget should do when an image fails to load. The function exposes the exception `Object` and `StackTrace` to use in your implementation. |
153153
| `shrinkWrap` | A `bool` used while rendering different widgets to specify whether they should be shrink-wrapped or not, like `ContainerSpan` |
154154
| `onImageTap` | A function that defines what the widget should do when an image is tapped. The function exposes the `src` of the image as a `String` to use in your implementation. |
@@ -231,7 +231,7 @@ Widget html = Html(
231231

232232
Inner links (such as `<a href="#top">Back to the top</a>` will work out of the box by scrolling the viewport, as long as your `Html` widget is wrapped in a scroll container such as a `SingleChildScrollView`.
233233

234-
### customRender:
234+
### customRenders:
235235

236236
A powerful API that allows you to customize everything when rendering a specific HTML tag. This means you can change the default behaviour or add support for HTML elements that aren't supported natively. You can also make up your own custom tags in your HTML!
237237

@@ -243,7 +243,7 @@ The `CustomRender` class has two constructors: `CustomRender.fromWidget()` and `
243243

244244
To use this API, create a matching function and an instance of `CustomRender`.
245245

246-
#### Example Usages - customRender:
246+
#### Example Usages - customRenders:
247247
1. Simple example - rendering custom HTML tags
248248

249249
```dart
@@ -253,7 +253,7 @@ Widget html = Html(
253253
<flutter></flutter>
254254
<flutter horizontal></flutter>
255255
""",
256-
customRender: {
256+
customRenders: {
257257
birdMatcher(): CustomRender.fromInlineSpan(inlineSpan: (context, buildChildren) => TextSpan(text: "🐦")),
258258
flutterMatcher(): CustomRender.fromWidget(widget: (context, buildChildren) => FlutterLogo(
259259
style: (context.tree.element!.attributes['horizontal'] != null)
@@ -271,7 +271,9 @@ CustomRenderMatcher flutterMatcher() => (context) => context.tree.element?.local
271271
```
272272

273273
2. Complex example - wrapping the default widget with your own, in this case placing a horizontal scroll around a (potentially too wide) table.
274-
//todo
274+
275+
Note: Requires the [`flutter_html_table`](#flutter_html_table) package.
276+
275277
<details><summary>View code</summary>
276278

277279
```dart
@@ -284,15 +286,17 @@ Widget html = Html(
284286
<tr> <td>\90</td> <td>\$60</td> <td>\$80</td> <td>\$80</td> <td>\$100</td> <td>\$160</td> <td>\$150</td> <td>\$110</td> <td>\$100</td> <td>\$60</td> <td>\$30</td> <td>\$80</td> </tr>
285287
</table>
286288
""",
287-
customRender: {
288-
"table": (context, child) {
289+
customRenders: {
290+
tableMatcher(): CustomRender.fromWidget(widget: (context, child) {
289291
return SingleChildScrollView(
290292
scrollDirection: Axis.horizontal,
291293
child: (context.tree as TableLayoutElement).toWidget(context),
292294
);
293-
}
295+
}),
294296
},
295297
);
298+
299+
CustomRenderMatcher tableMatcher() => (context) => context.tree.element?.localName == "table";
296300
```
297301

298302
3. Complex example - rendering an `iframe` differently based on whether it is an embedded youtube video or some other embedded content.
@@ -307,7 +311,7 @@ Widget html = Html(
307311
<h3>YouTube iframe:</h3>
308312
<iframe src="https://www.youtube.com/embed/tgbNymZ7vqY"></iframe>
309313
""",
310-
customRender: {
314+
customRenders: {
311315
iframeYT(): CustomRender.fromWidget(widget: (context, buildChildren) {
312316
double? width = double.tryParse(context.tree.attributes['width'] ?? "");
313317
double? height = double.tryParse(context.tree.attributes['height'] ?? "");
@@ -700,7 +704,7 @@ The package considers the attributes `controls`, `loop`, `src`, `autoplay`, `wid
700704

701705
```dart
702706
Widget html = Html(
703-
customRender: {
707+
customRenders: {
704708
audioMatcher(): audioRender(),
705709
}
706710
);
@@ -718,7 +722,7 @@ Sandbox controls the JavaScript mode of the webview - a value of `null` or `allo
718722

719723
```dart
720724
Widget html = Html(
721-
customRender: {
725+
customRenders: {
722726
iframeMatcher(): iframeRender(),
723727
}
724728
);
@@ -730,7 +734,7 @@ You can set the `navigationDelegate` of the webview with the `navigationDelegate
730734

731735
```dart
732736
Widget html = Html(
733-
customRender: {
737+
customRenders: {
734738
iframeMatcher(): iframeRender(navigationDelegate: (NavigationRequest request) {
735739
if (request.url.contains("google.com/images")) {
736740
return NavigationDecision.prevent;
@@ -754,7 +758,7 @@ Because this package is parsing MathML to Tex, it may not support some functiona
754758

755759
```dart
756760
Widget html = Html(
757-
customRender: {
761+
customRenders: {
758762
mathMatcher(): mathRender(),
759763
}
760764
);
@@ -770,7 +774,7 @@ You can analyze the error and the parsed string, and finally return a new instan
770774

771775
```dart
772776
Widget html = Html(
773-
customRender: {
777+
customRenders: {
774778
mathMatcher(): mathRender(onMathError: (tex, exception, exceptionWithType) {
775779
print(exception);
776780
//optionally try and correct the Tex string here
@@ -793,7 +797,7 @@ Then, use the `customRender` parameter to add the widget to render Tex. It could
793797
```dart
794798
Widget htmlWidget = Html(
795799
data: r"""<tex>i\hbar\frac{\partial}{\partial t}\Psi(\vec x,t) = -\frac{\hbar}{2m}\nabla^2\Psi(\vec x,t)+ V(\vec x)\Psi(\vec x,t)</tex>""",
796-
customRender: {
800+
customRenders: {
797801
texMatcher(): CustomRender.fromWidget(widget: (context, buildChildren) => Math.tex(
798802
context.tree.element?.innerHtml ?? '',
799803
mathStyle: MathStyle.display,
@@ -821,7 +825,7 @@ The package also exposes a few ways to render SVGs within an `<img>` tag, specif
821825

822826
```dart
823827
Widget html = Html(
824-
customRender: {
828+
customRenders: {
825829
svgTagMatcher(): svgTagRender(),
826830
svgDataUriMatcher(): svgDataImageRender(),
827831
svgAssetUriMatcher(): svgAssetImageRender(),
@@ -840,7 +844,7 @@ When rendering table elements, the package tries to calculate the best fit for e
840844

841845
```dart
842846
Widget html = Html(
843-
customRender: {
847+
customRenders: {
844848
tableMatcher(): tableRender(),
845849
}
846850
);
@@ -856,7 +860,7 @@ The package considers the attributes `controls`, `loop`, `src`, `autoplay`, `pos
856860

857861
```dart
858862
Widget html = Html(
859-
customRender: {
863+
customRenders: {
860864
videoMatcher(): videoRender(),
861865
}
862866
);

example/lib/main.dart

Lines changed: 4 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -267,31 +267,7 @@ class _MyHomePageState extends State<MyHomePage> {
267267
),
268268
'h5': Style(maxLines: 2, textOverflow: TextOverflow.ellipsis),
269269
},
270-
customRender: {
271-
"table": (context, child) {
272-
return SingleChildScrollView(
273-
scrollDirection: Axis.horizontal,
274-
child:
275-
(context.tree as TableLayoutElement).toWidget(context),
276-
);
277-
},
278-
"bird": (RenderContext context, Widget child) {
279-
return TextSpan(text: "🐦");
280-
},
281-
"flutter": (RenderContext context, Widget child) {
282-
return FlutterLogo(
283-
style: (context.tree.element!.attributes['horizontal'] != null)
284-
? FlutterLogoStyle.horizontal
285-
: FlutterLogoStyle.markOnly,
286-
textColor: context.style.color!,
287-
size: context.style.fontSize!.size! * 5,
288-
);
289-
},
290-
},
291-
customImageRenders: {
292-
networkSourceMatcher(domains: ["flutter.dev"]):
293-
(context, attributes, element) {
294-
tagsList: Html.tags..addAll(["tex", "bird", "flutter"]),
270+
tagsList: Html.tags..addAll(['tex', 'bird', 'flutter']),
295271
customRenders: {
296272
texMatcher(): CustomRender.fromWidget(widget: (context, buildChildren) => Math.tex(
297273
context.tree.element?.innerHtml ?? '',
@@ -325,15 +301,15 @@ class _MyHomePageState extends State<MyHomePage> {
325301
svgNetworkSourceMatcher(): svgNetworkImageRender(),
326302
networkSourceMatcher(domains: ["flutter.dev"]): CustomRender.fromWidget(
327303
widget: (context, buildChildren) {
328-
return FlutterLogo(size: 36);
329-
}),
304+
return FlutterLogo(size: 36);
305+
}),
330306
networkSourceMatcher(domains: ["mydomain.com"]): networkImageRender(
331307
headers: {"Custom-Header": "some-value"},
332308
altWidget: (alt) => Text(alt ?? ""),
333309
loadingWidget: () => Text("Loading..."),
334310
),
335311
// On relative paths starting with /wiki, prefix with a base url
336-
(context) => context.tree.element?.attributes["src"] != null
312+
(context) => context.tree.element?.attributes["src"] != null
337313
&& context.tree.element!.attributes["src"]!.startsWith("/wiki"):
338314
networkImageRender(mapUrl: (url) => "https://upload.wikimedia.org" + url!),
339315
// Custom placeholder image for broken links

packages/flutter_html_svg/lib/flutter_html_svg.dart

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,8 @@ CustomRender svgAssetImageRender() => CustomRender.fromWidget(widget: (context,
4545
if ( _src(context.tree.element?.attributes.cast() ?? <String, String>{}) == null) {
4646
return Container(height: 0, width: 0);
4747
}
48-
return SvgPicture.asset( _src(context.tree.element!.attributes.cast())!);
48+
final assetPath = _src(context.tree.element!.attributes.cast())!.replaceFirst('asset:', '');
49+
return SvgPicture.asset(assetPath);
4950
});
5051

5152
CustomRenderMatcher svgTagMatcher() => (context) {

0 commit comments

Comments
 (0)