flutter_widget_from_html

repository·master·Indexed 20 days ago

https://github.com/daohoangson/flutter_widget_from_html

A collection of Flutter packages to render HTML content as Flutter widgets. It includes a core rendering engine (flutter_widget_from_html_core) supporting over 70 tags and extensive inline CSS, as well as an enhanced version (flutter_widget_from_html) with support for AUDIO, VIDEO, IFRAME, and SVG. The monorepo also provides specialized extensions like fwfh_cached_network_image, fwfh_chewie for video, and fwfh_just_audio for audio playback.

Tokens
10.4K
Snippets
30
Records
52
Agent score
73%

What's inside flutter_widget_from_html

  1. Overview of the HtmlWidget monorepo packages

    master

    The HtmlWidget monorepo provides a suite of packages for rendering HTML in Flutter applications. The core functionality is split between a high-level widget package and a core logic package, with various specialized plugins available for extended media support.

    Core Packages

    • flutter_widget_from_html: The primary package for rendering HTML widgets.
    • flutter_widget_from_html_core: The core logic used by the main widget package.

    Specialized Extension Packages

    Use these packages to add support for specific HTML elements or media types:

    • fwfh_cached_network_image: For cached network images.
    • fwfh_chewie: For video playback using Chewie.
    • fwfh_just_audio: For audio playback using just_audio.
    • fwfh_svg: For rendering SVG images.
    • fwfh_url_launcher: For handling URL links.
    • fwfh_webview: For embedding web views.
  2. Use BuildOp.inline for custom inline widgets

    master
    In version 0.14, a new factory BuildOp.inline was introduced to simplify the rendering of custom inline widgets. If you were previously using onTree combined with detach, insertAfter, or insertBefore to inject inline elements, you should switch to BuildOp.inline for a more streamlined approach.
  3. Replace tree modification methods with BuildOp.onParsed

    master

    Starting from version 0.14, methods like detach(), insertAfter(), and insertBefore() should no longer be used to modify the build tree. Instead, use the BuildOp.onParsed callback and return an entirely new tree.

    Example Migration:

    Before (v0.10):

    final oldOp = BuildOp(
      onTreeFlattening: (meta, tree) {
        final foo = WidgetBit.inline(tree.parent!, Text('foo'));
        foo.insertBefore(tree);
        tree.detach();
      }
    )

    After (v0.14):

    final newOp = BuildOp(
      onParsed: (tree) {
        final newTree = tree.parent.sub();
        newTree.append(WidgetBit.inline(tree, Text('foo')));
        return newTree;
      }
    )
    final newOp = BuildOp(
      onParsed: (tree) {
        final newTree = tree.parent.sub();
        newTree.append(WidgetBit.inline(tree, Text('foo')));
        return newTree;
      }
    )
  4. Migrate BuildBit implementation from v0.10 to v0.14

    master

    In version 0.14, the BuildBit class was simplified and no longer uses generic type arguments. The buildBit method has been replaced by flatten, which uses a Flattened object to explicitly define how content is added to the tree. This replaces the previous dynamic interpretation of types (where String was automatically text, etc.) with explicit method calls.

    To migrate, implement the flatten method using the following Flattened interface:

    abstract class Flattened {
      void inlineWidget({ required Widget child });
      void widget(Widget value);
      void write({String? text, String? whitespace});
    }
    abstract class BuildBit {
      void flatten(Flattened f);
    }
  5. Customize the iOS launch screen assets

    master

    To change the launch screen image for the iOS version of the app, you can use one of two methods:

    1. Direct File Replacement: Replace the existing image files located in the demo_app/ios/Runner/Assets.xcassets/LaunchImage.imageset/ directory with your own assets.
    2. Xcode Interface:
      • Open the iOS project in Xcode by running open ios/Runner.xcworkspace from your terminal.
      • In the Xcode Project Navigator, navigate to Runner/Assets.xcassets.
      • Drag and drop your desired images into the asset catalog to replace the existing ones.
    open ios/Runner.xcworkspace
  6. Migrate BuildOp configuration and callbacks to v0.14

    master

    The BuildOp constructor and its callbacks have been updated in version 0.14. BuildMetadata and BuildTree are now merged, so callbacks receive a single argument. Many callback names have changed to be more descriptive.

    Key Changes:

    • onTree is now onParsed (returns a new tree).
    • onWidgets is now onRenderBlock (handles WidgetPlaceholder).
    • onChild is now onVisitChild.
    • defaultStyles now returns a StylesMap and styles are appended to the end of the list rather than the beginning.

    Example Migration:

    Before (v0.10):

    final oldOp = BuildOp({
      defaultStyles: (dom.Element element) {
        final Map<String, String> styles = {'color': 'red'};
        return styles;
      },
      onChild: (BuildMetadata childMeta) {},
      onTree: (BuildMetadata meta, BuildTree tree) {},
      onTreeFlattening: (BuildMetadata meta, BuildTree tree) {
        // ...
      },
      onWidgets: (BuildMetadata meta, Iterable<WidgetPlaceholder> widgets) {
        final Iterable<Widget> results = [Container()];
        return results;
      },
      onWidgetsIsOptional: false,
      priority: 10,
    })

    After (v0.14):

    final newOp = BuildOp(
      alwaysRenderBlock: true,
      debugLabel: 'v0.14',
      defaultStyles: (dom.Element element) {
        final StylesMap styles = {'color': 'red'};
        return styles;
      },
      onParsed: (BuildTree tree) => tree,
      onRenderBlock: (BuildTree tree, WidgetPlaceholder placeholder) {
        return Container();
      },
      onRenderInline: (BuildTree tree) {},
      onRenderedBlock: (BuildTree tree, Widget block) {
        // ...
      },
      onVisitChild: (BuildTree tree, BuildTree subTree) {
        // ...
      },
      priority: 10,
    )
    final newOp = BuildOp(
      alwaysRenderBlock: true,
      debugLabel: 'v0.14',
      defaultStyles: (dom.Element element) {
        final StylesMap styles = {'color': 'red'};
        return styles;
      },
      onParsed: (BuildTree tree) => tree,
      onRenderBlock: (BuildTree tree, WidgetPlaceholder placeholder) {
        return Container();
      },
      onRenderInline: (BuildTree tree) {},
      onRenderedBlock: (BuildTree tree, Widget block) {},
      onVisitChild: (BuildTree tree, BuildTree subTree) {},
      priority: 10,
    )