diff --git a/.circleci/config.yml b/.circleci/config.yml deleted file mode 100644 index 16c40c66b9..0000000000 --- a/.circleci/config.yml +++ /dev/null @@ -1,13 +0,0 @@ -version: 2.1 -orbs: - codecov: codecov/codecov@1.0.2 -jobs: - build: - docker: - - image: cirrusci/flutter - steps: - - checkout - - run: flutter --version - - run: flutter test --coverage - - codecov/upload: - file: coverage/lcov.info diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml index 6418d1dee6..6627ba6868 100644 --- a/.github/FUNDING.yml +++ b/.github/FUNDING.yml @@ -1,6 +1,6 @@ # These are supported funding model platforms -github: # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2] +github: Sub6Resources patreon: # Replace with a single Patreon username open_collective: flutter_html ko_fi: # Replace with a single Ko-fi username diff --git a/.github/flutter_html_screenshot.png b/.github/flutter_html_screenshot.png deleted file mode 100644 index 3d1b893b61..0000000000 Binary files a/.github/flutter_html_screenshot.png and /dev/null differ diff --git a/.github/flutter_html_screenshot2.png b/.github/flutter_html_screenshot2.png deleted file mode 100644 index eb47b0e146..0000000000 Binary files a/.github/flutter_html_screenshot2.png and /dev/null differ diff --git a/.github/flutter_html_screenshot3.png b/.github/flutter_html_screenshot3.png deleted file mode 100644 index 75a065879d..0000000000 Binary files a/.github/flutter_html_screenshot3.png and /dev/null differ diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml new file mode 100644 index 0000000000..3bd2e1fd11 --- /dev/null +++ b/.github/workflows/test.yml @@ -0,0 +1,33 @@ +name: flutter_html tests + +on: + pull_request: + branches: [ master ] + push: + branches: [ master ] + +jobs: + test: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: dart-lang/setup-dart@v1 + - uses: flutter-actions/setup-flutter@54feb1e258158303e041b9eaf89314dcfbf6d38a + - name: Setup Melos + run: flutter pub global activate melos + - name: Bootstrap Project + run: melos bootstrap + - name: Run Test Suite + run: flutter pub global run melos run test + - name: Compile Test Coverage Report + run: flutter pub global run melos run gen_coverage + - name: Upload Coverage to Codecov + uses: codecov/codecov-action@v5 + with: + files: coverage_report/lcov.info + disable_search: true + token: ${{ secrets.CODECOV_TOKEN }} + - name: Run Dart Analysis + run: flutter pub global run melos analyze --fatal-infos + - name: Check that `dart format` has been run on every file + run: dart format -o none --set-exit-if-changed . diff --git a/.gitignore b/.gitignore index 34258e6aad..188d2e1fa5 100644 --- a/.gitignore +++ b/.gitignore @@ -151,3 +151,9 @@ modules.xml **/flutter_export_environment.sh /example/ios/Flutter/Flutter.podspec + +packages/**/pubspec_overrides.yaml +./pubspec_overrides.yaml +/example/pubspec_overrides.yaml + +coverage/ \ No newline at end of file diff --git a/CHANGELOG.md b/CHANGELOG.md index 625d0f4897..13a7fda044 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,128 @@ +# Change Log + +All notable changes to this project will be documented in this file. +See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. + +#### 3.0.0 *March 2025* + + - Graduate package to a stable release. See pre-releases prior to this version for changelog entries. + +#### 3.0.0-beta.2 *May 2023* + + - Several Breaking Changes. See the [migration guide](https://github.com/Sub6Resources/flutter_html/wiki/Migration-Guides#300) + + - **FIX**: start list items on a new line ([#1281](https://github.com/sub6resources/flutter_html/issues/1281)). ([496d1aa8](https://github.com/sub6resources/flutter_html/commit/496d1aa8e655891d2f597c5e4d7e92057801d815)) + - **FIX**: Add "display: Display.block" to table ([#1278](https://github.com/sub6resources/flutter_html/issues/1278)). ([6350f023](https://github.com/sub6resources/flutter_html/commit/6350f02354b7de601ce294123717e2051be97eee)) + - **FIX**: improve API for ExtensionContext and export marker.dart ([#1273](https://github.com/sub6resources/flutter_html/issues/1273)). ([27e33a95](https://github.com/sub6resources/flutter_html/commit/27e33a955e872d47306db9480f74f6da2e9a028a)) + - **FIX**: Cleaned up whitespace processing and added whitespace tests ([#1267](https://github.com/sub6resources/flutter_html/issues/1267)). ([cc00406b](https://github.com/sub6resources/flutter_html/commit/cc00406b1d0c115e5c66dd4bdfb40db32496f55f)) + - **FIX**: a tag should not style as link if href is not provided ([#1265](https://github.com/sub6resources/flutter_html/issues/1265)). ([d7247cb3](https://github.com/sub6resources/flutter_html/commit/d7247cb303c25d0011f85f9b2d3687924de3d83d)) + - **FEAT**: Update CssBoxWidget to handle rtl marker boxes ([#1270](https://github.com/sub6resources/flutter_html/issues/1270)). ([d7091990](https://github.com/sub6resources/flutter_html/commit/d7091990d193e892e2f782ac8d91fc0326aff4bc)) + - **FEAT**: support vertical-align in inline styles ([#1266](https://github.com/sub6resources/flutter_html/issues/1266)). ([fe896de5](https://github.com/sub6resources/flutter_html/commit/fe896de5ed8b79425bb33800a26fa4ac328057fe)) + - **FEAT**: Add WrapperExtension helper ([#1264](https://github.com/sub6resources/flutter_html/issues/1264)). ([2ffa1dda](https://github.com/sub6resources/flutter_html/commit/2ffa1ddabb3f2a660ab85c551255b89fe8a24ab5)) + + +#### 3.0.0-beta.1 - *May 2023* + + - Several Breaking Changes. See the [migration guide](https://github.com/Sub6Resources/flutter_html/wiki/Migration-Guides#300) + + - **FIX**: Aspect ratio exception when height is 0 ([#1222](https://github.com/sub6resources/flutter_html/issues/1222)). ([ed75f8fe](https://github.com/sub6resources/flutter_html/commit/ed75f8fef779e920ecc1f27719a4150a29e3ebee)) + - **FIX**: Fix issue with font scaling introduced in 3.0.0-alpha.6 ([#1173](https://github.com/sub6resources/flutter_html/issues/1173)). ([c75e0dfb](https://github.com/sub6resources/flutter_html/commit/c75e0dfb1be6cb79748f719487043d12bc330c60)) + - **FIX**: Fix various issues with list rendering. ([520ff3c3](https://github.com/sub6resources/flutter_html/commit/520ff3c326d5dc8f5a601022c2a32d58e2e83cbb)) + - **FIX**: Apply margins to properly. ([7581ea79](https://github.com/sub6resources/flutter_html/commit/7581ea798744b2830affaaf75bbdff016b03f7af)) + - **FIX**: Use enum instead of const int internally in length.dart. ([9dc7f08c](https://github.com/sub6resources/flutter_html/commit/9dc7f08ca238ff6a93314be5de716ad4e3baebb8)) + - **FIX**: Change CSSBoxWidget to CssBoxWidget. ([a62449a7](https://github.com/sub6resources/flutter_html/commit/a62449a77c18701a0faf8ffd650f9c535b2d006c)) + - **FEAT**: Support mmultiscripts. ([#1175](https://github.com/sub6resources/flutter_html/issues/1175)). ([a999a300](https://github.com/sub6resources/flutter_html/commit/a999a30027eff0aabb2825ffdbe383f9affab7f6)) + - **FEAT**: Support mfenced. ([#1174](https://github.com/sub6resources/flutter_html/issues/1174)). ([9ca23084](https://github.com/sub6resources/flutter_html/commit/9ca230848beb15332f96294083ed4989831130d7)) + - **FEAT**: Upgrade list-style-type to CSS3. ([deb726ae](https://github.com/sub6resources/flutter_html/commit/deb726ae2776f45305026c0aa081d4a5b5a1c71d)) + - **FEAT**: Support mtable, mtd, mtr for draw matrix. ([#1164](https://github.com/sub6resources/flutter_html/issues/1164)). ([e99e2cc1](https://github.com/sub6resources/flutter_html/commit/e99e2cc1553ab17b4ceff08f784e99283b28dff4)) + +## 3.0.0-alpha.6 - *September 2022* + + - **FIX** #731 Resolve newline `
` issue + - **FIX** Align the baseline of inline content with the baseline of its parent flow, even if it has padding or borders + - **FIX** Improved fontSize inheritance when cascading styles + - **FIX** `auto` margins now work for any `Display.BLOCK` element. + - **FIX** `auto` width and height is now the default, rather than `null` + - **FIX** New CSSBoxWidget that handles calculations of child sizes for a more accurate HTML/CSS layout + - **BREAKING** New `Margin`, `Height`, and `Width` classes that allow `em`, `rem`, `px`, `auto`, and `%` values to be given + - **FEAT** Negative margins are now allowed + - **FIX** Updated default `p` and `h1-6` styles to use `em` for better font scaling + - **BREAKING** Package now requires Dart sdk >= Dart 2.17 + - **FIX**: Apply margins to
properly. (7581ea79) + - **FIX**: Use enum instead of const int internally in length.dart. (9dc7f08c) + - **FIX**: Change CSSBoxWidget to CssBoxWidget. (a62449a7) + - **FIX**: fix textShadow color declaration handler. (77ffe7cb) + - **FIX**: ol use default style. (1c2412a2) + - **FIX**: Crash when a tr tag includes text node. (ba8301c9) + - **FEAT**: exposes fontFamilyFallback parameter. (1d65aafd) + +## [3.0.0-alpha.5] - June 9, 2022: +* Fixed hot reloads, thanks @arjenmels +* Fixed link taps not working +* Improvements in README + +## [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 + +## [3.0.0-alpha.1] - December 21, 2021: +* **BREAKING** Reworked custom renders pending full modularation in 3.0.0 +* Extended support custom render when using SelectableHtml +* Updated flutter_svg to 1.0.0 +* Support flutter_webview 3.x +* Automatic disposal of video and audio controllers +* Fix block elements bottom spacing in table cells + +## [2.2.1] - December 8, 2021: +* Allow styling on ruby tags +* Allow width/height/alignment styling on table/tr/td tags +* Prevent images causing rebuilding and leaking memory +* Fixes display of list items on iOS with font weights below 400 +* Prevent crash on negative margins or paddings + +## [2.2.0] - November 29, 2021: +* Explicitly declare multiplatform support +* Extended and fixed list-style (marker) support +* Basic support for height/width css properties +* Support changing scroll physics of SelectableText.rich +* Support text transform css property +* Bumped minimum flutter_math_fork version for Flutter 2.5 compatibility +* Fix styling of iframes +* Fix nested font tag application +* Fix whitespace rendering between list items +* Prevent crash on empty
tag and tables with both colspan/rowspan +* Prevent crash on use of negative margins in css + +## [2.1.5] - October 7, 2021: +* Ignore unsupported custom style selectors when using fromCss +* Fix SVG tag usage inside tables +* Properly fix regression in usage of line breaks + +## [2.1.4] - October 3, 2021: +* Fix regression in usage of line breaks in body being stripped + +## [2.1.3] - October 1, 2021: +* Update minimum versions of dependencies for Flutter 2.5 compatibility +* Extended and fixed support for css shadow +* Fix block tags with explicit whitespace from being stripped + +## [2.1.2] - September 2, 2021: +* Allow setting selectionControls with SelectableHtml +* Fix onLinkTap not working with SelectableHtml +* Don't crash when parsing unsupported :hover +* Prevent endless loading when using animated images + +## [2.1.1] - July 28, 2021: +* Stable release with all 2.1.1-preview.X changes + +## [2.1.1-preview.0] - July 27, 2021: +* Improves hr tag support +* Fixes a leading whitespace issue +* Fixes some crashes with CSS parsing + ## [2.1.0] - June 3, 2021: * SelectableHtml widget (supporting a subset of tags) which allow text selection * Fixed shrinkWrap to actually shrink the horizontal space diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 2dc1383211..02466657d6 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -1,8 +1,3 @@ Thanks for your interest in contributing to `flutter_html`! -I'm pretty busy, so in order to help me best make use of the time I spend working on this project, please adhere to the following guidelines when contributing: - -1. In general, don't submit a pull request without discussing the feature with me, in an issue, first. I don't want you to have to do a whole bunch of work for nothing. This also makes it so there won't be a whole bunch of changes I make you do in order to have your pull request merged. -2. Please read the [wiki](https://github.com/Sub6Resources/flutter_html/wiki) before contributing (there are only two pages at the moment). This will give you an idea of what my plans are for this repository, and what you do and don't need to work on. - -More specific guidelines will be added soon. +Please see the contribution guide in the wiki: https://github.com/Sub6Resources/flutter_html/wiki/Contributing diff --git a/LICENSE b/LICENSE index b0f300d959..230b35b47f 100644 --- a/LICENSE +++ b/LICENSE @@ -1,6 +1,6 @@ MIT License -Copyright (c) 2019 Matthew Whitaker +Copyright (c) 2019-2025 The flutter_html developers Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/README.md b/README.md index 80deef14bb..adea04a977 100644 --- a/README.md +++ b/README.md @@ -1,141 +1,93 @@ # flutter_html [![pub package](https://img.shields.io/pub/v/flutter_html.svg)](https://pub.dev/packages/flutter_html) [![codecov](https://codecov.io/gh/Sub6Resources/flutter_html/branch/master/graph/badge.svg)](https://codecov.io/gh/Sub6Resources/flutter_html) -[![CircleCI](https://circleci.com/gh/Sub6Resources/flutter_html.svg?style=svg)](https://circleci.com/gh/Sub6Resources/flutter_html) +[![GitHub Actions](https://github.com/Sub6Resources/flutter_html/actions/workflows/test.yml/badge.svg)](https://github.com/Sub6Resources/flutter_html/actions) [![MIT License](https://img.shields.io/badge/license-MIT-blue.svg?style=flat)](https://github.com/Sub6Resources/flutter_html/blob/master/LICENSE) A Flutter widget for rendering HTML and CSS as Flutter widgets. -
- - - - - - - - - - -
Screenshot 1Screenshot 2Screenshot 3
A Screenshot of flutter_htmlAnother Screenshot of flutter_htmlYet another Screenshot of flutter_html
+```dart +Widget build(context) { + return Html( + data: """ +

Hello, World!

+

flutter_html supports a variety of HTML and CSS tags and attributes.

+

Over a hundred static tags are supported out of the box.

+

Or you can even define your own using an Extension:

+

Its easy to add custom styles to your Html as well using the Style class:

+

Here's a fancy <p> element!

+ """, + extensions: [ + TagExtension( + tagsToExtend: {"flutter"}, + child: const FlutterLogo(), + ), + ], + style: { + "p.fancy": Style( + textAlign: TextAlign.center, + padding: const EdgeInsets.all(16), + backgroundColor: Colors.grey, + margin: Margins(left: Margin(50, Unit.px), right: Margin.auto()), + width: Width(300, Unit.px), + fontWeight: FontWeight.bold, + ), + }, + ); +} +``` -## Table of Contents: +becomes... -- [Installing](#installing) +A screenshot showing the above code snippet rendered using flutter_html -- [Currently Supported HTML Tags](#currently-supported-html-tags) +## Table of Contents: -- [Currently Supported CSS Attributes](#currently-supported-css-attributes) +- [Supported HTML Tags](https://github.com/Sub6Resources/flutter_html/wiki/Supported-HTML-Elements) -- [Currently Supported Inline CSS Attributes](#currently-supported-inline-css-attributes) +- [Supported CSS Attributes](https://github.com/Sub6Resources/flutter_html/wiki/Supported-CSS-Attributes) - [Why flutter_html?](#why-this-package) +- [Migration Guide](#migration-guides) + - [API Reference](#api-reference) - [Constructors](#constructors) - - - [Selectable Text](#selectable-text) - [Parameters Table](#parameters) - - [Getters](#getters) - - - [Data](#data) - - - [Document](#document) - - - [onLinkTap](#onlinktap) - - - [customRender](#customrender) - - - [onImageError](#onimageerror) - - - [onMathError](#onmatherror) - - - [onImageTap](#onimagetap) - - - [tagsList](#tagslist) - - - [style](#style) - - - [navigationDelegateForIframe](#navigationdelegateforiframe) - - - [customImageRender](#customimagerender) - - - [typedef ImageSourceMatcher (with examples)](#typedef-imagesourcematcher) - - - [typedef ImageRender (with examples)](#typedef-imagerender) - - - [Extended examples](#example-usages---customimagerender) - -- [Rendering Reference](#rendering-reference) - - - [Image](#image) - - - [Iframe](#iframe) +- [External Packages](#external-packages) - - [Audio](#audio) + - [`flutter_html_all`](#flutter_html_all) - - [Video](#video) + - [`flutter_html_audio`](#flutter_html_audio) - - [SVG](#svg) + - [`flutter_html_iframe`](#flutter_html_iframe) - - [MathML](#mathml) + - [`flutter_html_math`](#flutter_html_math) - - [Tex](#tex) + - [`flutter_html_svg`](#flutter_html_svg) - - [Table](#table) - -- [Notes](#notes) - -- [Migration Guide](#migration-guides) + - [`flutter_html_table`](#flutter_html_table) -- [Contribution Guide](#contribution-guide) - -## Installing: - -Add the following to your `pubspec.yaml` file: - - dependencies: - flutter_html: ^2.1.0 + - [`flutter_html_video`](#flutter_html_video) + +- [Frequently Asked Questions](#faq) -## Currently Supported HTML Tags: -| | | | | | | | | | | | -|------------|-----------|-------|-------------|---------|---------|-------|------|--------|--------|--------| -|`a` | `abbr` | `acronym`| `address` | `article`| `aside` | `audio`| `b` | `bdi` | `bdo` | `big` | -|`blockquote`| `body` | `br` | `caption` | `cite` | `code` | `data`| `dd` | `del` | `details` | `dfn` | -| `div` | `dl` | `dt` | `em` | `figcaption`| `figure`| `footer`| `font` | `h1` | `h2` | `h3` | -| `h4` | `h5` |`h6` | `header` | `hr` | `i` | `iframe`| `img` | `ins` | `kbd`| `li` | -| `main` | `mark` | `nav` | `noscript`|`ol` | `p` | `pre` | `q` | `rp` | `rt` | `ruby` | -| `s` | `samp` | `section` | `small` | `span`| `strike` | `strong`| `sub` | `sup` | `summary` | `svg`| -| `table` | `tbody` | `td` | `template` | `tfoot` | `th` | `thead` |`time` | `tr` | `tt` | `u` | -| `ul` | `var` | `video` | `math`: | `mrow` | `msup` | `msub` | `mover` | `munder` | `msubsup` | `moverunder` | -| `mfrac` | `mlongdiv` | `msqrt` | `mroot` | `mi` | `mn` | `mo` | | | | | +- [Example](#example) - -## Currently Supported CSS Attributes: -| | | | | | | | -|------------------|--------|------------|----------|--------------|------------------------|------------| -|`background-color`| `color`| `direction`| `display`| `font-family`| `font-feature-settings`| `font-size`| -|`font-style` | `font-weight`| `height` | `letter-spacing`| `line-height`| `list-style-type` | `list-style-position`| -|`padding` | `margin`| `text-align`| `text-decoration`| `text-decoration-color`| `text-decoration-style`| `text-decoration-thickness`| -|`text-shadow` | `vertical-align`| `white-space`| `width` | `word-spacing`| | | - -## Currently Supported Inline CSS Attributes: -| | | | | | | | -|------------------|--------|------------|----------|--------------|------------------------|------------| -|`background-color`| `border` (including specific directions) | `color`| `direction`| `display`| `font-family`| `font-feature-settings` | -| `font-size`|`font-style` | `font-weight`| `line-height` | `list-style-type` | `list-style-position`|`padding` (including specific directions) | -| `margin` (including specific directions) | `text-align`| `text-decoration`| `text-decoration-color`| `text-decoration-style`| `text-shadow` | | - -Don't see a tag or attribute you need? File a feature request or contribute to the project! ## Why this package? This package is designed with simplicity in mind. Originally created to allow basic rendering of HTML content into the Flutter widget tree, this project has expanded to include support for basic styling as well! -If you need something more robust and customizable, the package also provides a number of optional custom APIs for extremely granular control over widget rendering! + +If you need something more robust and customizable, the package also provides a number of extension APIs for extremely granular control over widget rendering! + +## Migration Guides + +[3.0.0 Migration Guide](https://github.com/Sub6Resources/flutter_html/wiki/Migration-Guides#300) ## API Reference: @@ -153,695 +105,253 @@ The `Html()` constructor is for those who would like to directly pass HTML from If you would like to modify or sanitize the HTML before rendering it, then `Html.fromDom()` is for you - you can convert the HTML string to a `Document` and use its methods to modify the HTML as you wish. Then, you can directly pass the modified `Document` to the package. This eliminates the need to parse the modified `Document` back to a string, pass to `Html()`, and convert back to a `Document`, thus cutting down on load times. -#### Selectable Text +### Parameters: -The package also has two constructors for selectable text support - `SelectableHtml()` and `SelectableHtml.fromDom()`. +| Parameters | Description | +|------------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| +| `data` | The HTML data passed to the `Html` widget. This is required and cannot be null when using `Html()`. | +| `document` | The DOM document passed to the `Html` widget. This is required and cannot be null when using `Html.fromDom()`. | +| `onLinkTap` | Optional. 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. | +| `extensions` | Optional. A powerful API that allows you to customize everything when rendering a specific HTML tag. | +| `shrinkWrap` | Optional. A `bool` used while rendering different widgets to specify whether they should be shrink-wrapped or not, like `ContainerSpan` | +| `onlyRenderTheseTags` | Optional. An exclusive set of elements the `Html` widget should render. Note that your html will be wrapped in `` and `` if it isn't already, so you should include those in this list. | +| `doNotRenderTheseTags` | Optional. A set of tags that should not be rendered by the `Html` widget. | +| `style` | Optional. A powerful API that allows you to customize the style that should be used when rendering a specific HTMl tag. | -The difference between the two is the same as noted above. -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: +More examples and in-depth details are available: -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. + - [Style](https://github.com/Sub6Resources/flutter_html/wiki/How-To-Use-Style). + - [HtmlExtension](https://github.com/Sub6Resources/flutter_html/wiki/How-To-Use-Extensions) -2. No support for `customRender`, `customImageRender`, `onImageError`, `onImageTap`, `onMathError`, and `navigationDelegateForIframe`. (Support for `customRender` may be added in the future). +## External Packages -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. +### `flutter_html_all` -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. +This package is simply a convenience package that exports all the other external packages below. You should use this if you plan to render all the tags that require external dependencies. -### Parameters: +### `flutter_html_audio` -| Parameters | Description | -|--------------|-----------------| -| `data` | The HTML data passed to the `Html` widget. This is required and cannot be null when using `Html()`. | -| `document` | The DOM document passed to the `Html` widget. This is required and cannot be null when using `Html.fromDom()`. | -| `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. | -| `customRender` | A powerful API that allows you to customize everything when rendering a specific HTML tag. | -| `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. | -| `onMathError` | A function that defines what the widget should do when a math fails to render. The function exposes the parsed Tex `String`, as well as the error and error with type from `flutter_math` as a `String`. | -| `shrinkWrap` | A `bool` used while rendering different widgets to specify whether they should be shrink-wrapped or not, like `ContainerSpan` | -| `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. | -| `tagsList` | A list of elements the `Html` widget should render. The list should contain the tags of the HTML elements you wish to include. | -| `style` | A powerful API that allows you to customize the style that should be used when rendering a specific HTMl tag. | -| `navigationDelegateForIframe` | Allows you to set the `NavigationDelegate` for the `WebView`s of all the iframes rendered by the `Html` widget. | -| `customImageRender` | A powerful API that allows you to fully customize how images are loaded. | +This package renders audio elements using the [`chewie_audio`](https://pub.dev/packages/chewie_audio) and the [`video_player`](https://pub.dev/packages/video_player) plugin. -### Getters: - -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. - -2. `SelectableHtml.tags`. This provides a list of all the tags that can be rendered in selectable mode. +The package considers the attributes `controls`, `loop`, `src`, `autoplay`, `width`, and `muted` when rendering the audio widget. -### Data: +#### Adding the `AudioHtmlExtension`: -The HTML data passed to the `Html` widget as a `String`. This is required and cannot be null when using `Html`. -Any HTML tags in the `String` that are not supported by the package will not be rendered. +Add the dependency to your pubspec.yaml: -#### Example Usage - Data: + flutter pub add flutter_html_audio ```dart -Widget html = Html( - data: """
-

Demo Page

-

This is a fantastic product that you should buy!

-

Features

- - -
""", -); -``` +import 'package:flutter_html_audio/flutter_html_audio.dart'; -### Document: - -The DOM document passed to the `Html` widget as a `Document`. This is required and cannot be null when using `Html.fromDom()`. -Any HTML tags in the document that are not supported by the package will not be rendered. -Using the `Html.fromDom()` constructor can be useful when you would like to sanitize the HTML string yourself before passing it to the package. - -#### Example Usage - Document: - -```dart -import 'package:html/parser.dart' as htmlparser; -import 'package:html/dom.dart' as dom; -... -String htmlData = """
-

Demo Page

-

This is a fantastic product that you should buy!

-

Features

- - -
"""; -dom.Document document = htmlparser.parse(htmlData); -/// sanitize or query document here -Widget html = Html( - document: document, -); -``` - -### onLinkTap: - -A function that defines what the widget should do when a link is tapped. - -#### Example Usage - onLinkTap: - -```dart Widget html = Html( - data: """

- Linking to websites has never been easier. -

""", - onLinkTap: (String? url, RenderContext context, Map attributes, dom.Element? element) { - //open URL in webview, or launch URL in browser, or any other logic here - } + data: myHtml, + extensions: [ + AudioHtmlExtension(), + ], ); ``` -Inner links (such as `Back to the top` 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`. +### `flutter_html_iframe` -### customRender: +This package renders iframes using the [`webview_flutter`](https://pub.dev/packages/webview_flutter) plugin. -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! +When rendering iframes, the package considers the width, height, and sandbox attributes. -`customRender` accepts a `Map`. The `CustomRender` type is a function that requires a `Widget` or `InlineSpan` to be returned. It exposes `RenderContext` and the `Widget` that would have been rendered by `Html` without a `customRender` defined. The `RenderContext` contains the build context, styling and the HTML element, with attrributes and its subtree,. +Sandbox controls the JavaScript mode of the webview - a value of `null` or `allow-scripts` will set `javascriptMode: JavascriptMode.unrestricted`, otherwise it will set `javascriptMode: JavascriptMode.disabled`. -To use this API, set the key as the tag of the HTML element you wish to provide a custom implementation for, and create a function with the above parameters that returns a `Widget` or `InlineSpan`. +#### Adding the `IframeHtmlExtension`: -Note: If you add any custom tags, you must add these tags to the [`tagsList`](#tagslist) parameter, otherwise they will not be rendered. See below for an example. +Add the dependency to your pubspec.yaml: -#### Example Usages - customRender: -1. Simple example - rendering custom HTML tags + flutter pub add flutter_html_iframe ```dart -Widget html = Html( - data: """ -

Display bird element and flutter element

- - - """, - customRender: { - "bird": (RenderContext context, Widget child) { - return TextSpan(text: "🐦"); - }, - "flutter": (RenderContext context, Widget child) { - return FlutterLogo( - style: (context.tree.element!.attributes['horizontal'] != null) - ? FlutterLogoStyle.horizontal - : FlutterLogoStyle.markOnly, - textColor: context.style.color, - size: context.style.fontSize!.size! * 5, - ); - }, - }, - tagsList: Html.tags..addAll(["bird", "flutter"]), -); -``` - -2. Complex example - wrapping the default widget with your own, in this case placing a horizontal scroll around a (potentially too wide) table. +import 'package:flutter_html_iframe/flutter_html_iframe.dart'; -
View code - -```dart Widget html = Html( - data: """ - - - - - -
Monthly savings
January February March April May June July August September October November December
\$100 \$50 \$80 \$60 \$90 \$140 \$110 \$80 \$90 \$60 \$40 \$70
\90 \$60 \$80 \$80 \$100 \$160 \$150 \$110 \$100 \$60 \$30 \$80
- """, - customRender: { - "table": (context, child) { - return SingleChildScrollView( - scrollDirection: Axis.horizontal, - child: (context.tree as TableLayoutElement).toWidget(context), - ); - } - }, + data: myHtml, + extensions: [ + IframeHtmlExtension(), + ], ); ``` -
+You can set the `navigationDelegate` of the webview with the `navigationDelegate` property on `IframeHtmlExtension`. This allows you to block or allow the loading of certain URLs. -3. Complex example - rendering an `iframe` differently based on whether it is an embedded youtube video or some other embedded content. +### `flutter_html_math` -
View code +This package renders MathML elements using the [`flutter_math_fork`](https://pub.dev/packages/flutter_math_fork) plugin. -```dart -Widget html = Html( - data: """ -

Google iframe:

- -

YouTube iframe:

- - """, - customRender: { - "iframe": (RenderContext context, Widget child) { - final attrs = context.tree.element?.attributes; - if (attrs != null) { - double? width = double.tryParse(attrs['width'] ?? ""); - double? height = double.tryParse(attrs['height'] ?? ""); - return Container( - width: width ?? (height ?? 150) * 2, - height: height ?? (width ?? 300) / 2, - child: WebView( - initialUrl: attrs['src'] ?? "about:blank", - javascriptMode: JavascriptMode.unrestricted, - //no need for scrolling gesture recognizers on embedded youtube, so set gestureRecognizers null - //on other iframe content scrolling might be necessary, so use VerticalDragGestureRecognizer - gestureRecognizers: attrs['src'] != null && attrs['src']!.contains("youtube.com/embed") ? null : [ - Factory(() => VerticalDragGestureRecognizer()) - ].toSet(), - navigationDelegate: (NavigationRequest request) async { - //no need to load any url besides the embedded youtube url when displaying embedded youtube, so prevent url loading - //on other iframe content allow all url loading - if (attrs['src'] != null && attrs['src']!.contains("youtube.com/embed")) { - if (!request.url.contains("youtube.com/embed")) { - return NavigationDecision.prevent; - } else { - return NavigationDecision.navigate; - } - } else { - return NavigationDecision.navigate; - } - }, - ), - ); - } else { - return Container(height: 0); - } - } - } - ); -``` -
+When rendering MathML, the package takes the MathML data within the `` tag and tries to parse it to Tex. Then, it will pass the parsed string to `flutter_math_fork`. -More example usages and in-depth details available [here](https://github.com/Sub6Resources/flutter_html/wiki/All-About-customRender). +Because this package is parsing MathML to Tex, it may not support some functionalities. The current list of supported tags can be found [on the Wiki](https://github.com/Sub6Resources/flutter_html/wiki/First-Party-Extensions#flutter_html_math), but some of these only have partial support at the moment. -### onImageError: +#### Adding the `MathHtmlExtension`: -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. +Add the dependency to your pubspec.yaml: -#### Example Usage - onImageError: + flutter pub add flutter_html_math ```dart -Widget html = Html( - data: """Alt Text of an intentionally broken image""", - onImageError: (Exception exception, StackTrace stackTrace) { - FirebaseCrashlytics.instance.recordError(exception, stackTrace); - }, -); -``` - -### onMathError: +import 'package:flutter_html_math/flutter_html_math.dart'; -A function that defines what the widget should do when a math fails to render. The function exposes the parsed Tex `String`, as well as the error and error with type from `flutter_math` as a `String`. - -#### Example Usage - onMathError: - -```dart Widget html = Html( - data: """""", - onMathError: (String parsedTex, String error, String errorWithType) { - //your logic here. A Widget must be returned from this function: - return Text(error); - //you can also try and fix the parsing yourself: - return Math.tex(correctedParsedTex); - }, + data: myHtml, + extensions: [ + MathHtmlExtension(), + ], ); ``` -### onImageTap: - -A function that defines what the widget should do when an image is tapped. - -#### Example Usage - onImageTap: +If the parsing errors, you can use the `onMathErrorBuilder` property of `MathHtmlException` to catch the error and potentially fix it on your end. -```dart -Widget html = Html( - data: """Google""", - onImageTap: (String? url, RenderContext context, Map attributes, dom.Element? element) { - //open image in webview, or launch image in browser, or any other logic here - } -); -``` +The function exposes the parsed Tex `String`, as well as the error and error with type from `flutter_math_fork` as a `String`. -### tagsList: +You can analyze the error and the parsed string, and finally return a new instance of `Math.tex()` with the corrected Tex string. -A list of elements the `Html` widget should render. The list should contain the tags of the HTML elements you wish to whitelist. +#### Tex -#### Example Usage - tagsList - Excluding Tags: -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 `