From 9ee86eec781b4d8d992a1cee328f9baec2ff9fa1 Mon Sep 17 00:00:00 2001 From: MatthewWhitaker Date: Tue, 12 Mar 2019 18:31:51 -0600 Subject: [PATCH 001/533] Add initial structure for new parser --- lib/html_parser.dart | 46 ++++++++++++++++++++++++++++ lib/html_types.dart | 71 ++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 117 insertions(+) create mode 100644 lib/html_types.dart diff --git a/lib/html_parser.dart b/lib/html_parser.dart index 1b4b944165..e2ee7e9e10 100644 --- a/lib/html_parser.dart +++ b/lib/html_parser.dart @@ -4,6 +4,7 @@ import 'package:flutter/material.dart'; import 'package:flutter/gestures.dart'; import 'package:html/parser.dart' as parser; import 'package:html/dom.dart' as dom; +import 'package:flutter_html/html_types.dart'; typedef CustomRender = Widget Function(dom.Node node, List children); typedef OnLinkTap = void Function(String url); @@ -1722,3 +1723,48 @@ class HtmlOldParser extends StatelessWidget { return false; } } + +class HtmlParser extends StatelessWidget { + final String html; + + HtmlParser(this.html); + + @override + Widget build(BuildContext context) { + return parseTree(context, lexDomTree(parseHTML(html))); + } + + /// [parseHTML] converts a string to a DOM document using the dart `html` library. + static dom.Document parseHTML(String data) { + return parser.parse(data); + } + + /// [lexDomTree] converts a DOM document to a simplified tree of [StyledElement]s. + static StyledElement lexDomTree(dom.Document html) { + //TODO + } + + /// [cleanTree] optimizes the [StyledElement] tree so all [BlockElement]s are + /// on the first level and redundant levels are collapsed. + static StyledElement cleanTree(StyledElement tree) { + //TODO + } + + /// [parseTree] converts a tree of [StyledElement]s to a Flutter [Widget] tree. + static Widget parseTree(BuildContext context, StyledElement tree) { + //TODO + } +} + +/// A [CustomRenderer] is used to render html tags in your own way or implement unsupported tags. +class CustomRenderer { + final String name; + final Widget Function(BuildContext context) render; + final ElementType renderAs; + + CustomRenderer( + this.name, { + this.render, + this.renderAs, + }); +} diff --git a/lib/html_types.dart b/lib/html_types.dart new file mode 100644 index 0000000000..5ba997d090 --- /dev/null +++ b/lib/html_types.dart @@ -0,0 +1,71 @@ +const STYLED_ELEMENTS = [ + "b", +]; + +const INTERACTABLE_ELEMENTS = [ + "a", +]; + +const BLOCK_ELEMENTS = [ + "div", + +]; + +const CONTENT_ELEMENTS = [ + "img", +]; + +/// A [StyledElement] applies a style to all of its children. +class StyledElement { + final String name; + final List children; + final dynamic style; //TODO + + StyledElement({ + this.name, + this.children, + this.style, + }); +} + +/// A [Gesture] indicates the type of interaction by a user. +enum Gesture { + TAP, +} + +/// An [InteractableElement] is a [StyledElement] that takes user gestures (e.g. tap). +class InteractableElement extends StyledElement { + final void Function(Gesture gesture, dynamic data) onGesture; + + InteractableElement({ + this.onGesture, + }); +} + +/// A [Block] contains information about a [BlockElement] (width, height, padding, margins) +class Block { + //TODO +} + +/// A [BlockElement] is a [StyledElement] that wraps before and after the its [children]. +/// +/// A [BlockElement] may have a margin/padding or be a set width/height. +class BlockElement extends StyledElement { + final Block block; + + BlockElement({ + this.block, + }); +} + +/// A [ContentElement] is a type of [TextElement] that renders itself, but none of its [children]. +/// +/// A [ContentElement] may use its [children] to determine how it should render (e.g.