11library flutter_html;
22
33import 'package:flutter/material.dart' ;
4- import 'package:flutter_html/custom_render .dart' ;
5- import 'package:flutter_html/html_parser .dart' ;
4+ import 'package:flutter_html/src/html_parser .dart' ;
5+ import 'package:flutter_html/src/extension/extension .dart' ;
66import 'package:flutter_html/src/html_elements.dart' ;
7- import 'package:flutter_html/style.dart' ;
7+ import 'package:flutter_html/src/ style.dart' ;
88import 'package:html/dom.dart' as dom;
99
10- export 'package:flutter_html/custom_render.dart' ;
1110//export render context api
12- export 'package:flutter_html/html_parser.dart' ;
13- //export render context api
14- export 'package:flutter_html/html_parser.dart' ;
11+ export 'package:flutter_html/src/html_parser.dart' ;
1512//export src for advanced custom render uses (e.g. casting context.tree)
1613export 'package:flutter_html/src/anchor.dart' ;
17- export 'package:flutter_html/src/interactable_element.dart' ;
18- export 'package:flutter_html/src/layout_element.dart' ;
19- export 'package:flutter_html/src/replaced_element.dart' ;
20- export 'package:flutter_html/src/styled_element.dart' ;
21- //export css_box_widget for use in custom render.
14+ export 'package:flutter_html/src/tree/interactable_element.dart' ;
15+ export 'package:flutter_html/src/tree/replaced_element.dart' ;
16+ export 'package:flutter_html/src/tree/styled_element.dart' ;
17+ //export css_box_widget for use in extensions.
2218export 'package:flutter_html/src/css_box_widget.dart' ;
2319//export style api
24- export 'package:flutter_html/style.dart' ;
20+ export 'package:flutter_html/src/style.dart' ;
21+ //export extension api
22+ export 'package:flutter_html/src/extension/extension.dart' ;
2523
2624class Html extends StatefulWidget {
2725 /// The `Html` widget takes HTML as input and displays a RichText
@@ -33,9 +31,6 @@ class Html extends StatefulWidget {
3331 ///
3432 /// **onLinkTap** This function is called whenever a link (`<a href>` )
3533 /// is tapped.
36- /// **customRender** This function allows you to return your own widgets
37- /// for existing or custom HTML tags.
38- /// See [its wiki page] (https://github.com/Sub6Resources/flutter_html/wiki/All-About-customRender) for more info.
3934 ///
4035 /// **onImageError** This is called whenever an image fails to load or
4136 /// display on the page.
@@ -55,7 +50,7 @@ class Html extends StatefulWidget {
5550 required this .data,
5651 this .onLinkTap,
5752 this .onAnchorTap,
58- this .customRenders = const {} ,
53+ this .extensions = const [] ,
5954 this .onCssParseError,
6055 this .onImageError,
6156 this .shrinkWrap = false ,
@@ -73,7 +68,7 @@ class Html extends StatefulWidget {
7368 @required dom.Document ? document,
7469 this .onLinkTap,
7570 this .onAnchorTap,
76- this .customRenders = const {} ,
71+ this .extensions = const [] ,
7772 this .onCssParseError,
7873 this .onImageError,
7974 this .shrinkWrap = false ,
@@ -92,7 +87,7 @@ class Html extends StatefulWidget {
9287 @required this .documentElement,
9388 this .onLinkTap,
9489 this .onAnchorTap,
95- this .customRenders = const {} ,
90+ this .extensions = const [] ,
9691 this .onCssParseError,
9792 this .onImageError,
9893 this .shrinkWrap = false ,
@@ -136,9 +131,9 @@ class Html extends StatefulWidget {
136131 /// A list of HTML tags that are the only tags that are rendered. By default, this list is empty and all supported HTML tags are rendered.
137132 final List <String > tagsList;
138133
139- /// Either return a custom widget for specific node types or return null to
140- /// fallback to the default rendering .
141- final Map < CustomRenderMatcher , CustomRender > customRenders ;
134+ /// A list of [Extension] s that add additional capabilities to flutter_html
135+ /// See the [Extension] class for more details .
136+ final List < Extension > extensions ;
142137
143138 /// An API that allows you to override the default style for any HTML element
144139 final Map <String , Style > style;
@@ -147,8 +142,6 @@ class Html extends StatefulWidget {
147142 ..addAll (HtmlElements .interactableElements)
148143 ..addAll (HtmlElements .replacedElements)
149144 ..addAll (HtmlElements .layoutElements)
150- ..addAll (HtmlElements .tableCellElements)
151- ..addAll (HtmlElements .tableDefinitionElements)
152145 ..addAll (HtmlElements .externalElements);
153146
154147 @override
@@ -188,196 +181,9 @@ class _HtmlState extends State<Html> {
188181 onCssParseError: widget.onCssParseError,
189182 onImageError: widget.onImageError,
190183 shrinkWrap: widget.shrinkWrap,
191- selectable: false ,
192184 style: widget.style,
193- customRenders: {}
194- ..addAll (widget.customRenders)
195- ..addAll (generateDefaultRenders ()),
185+ extensions: widget.extensions,
196186 tagsList: widget.tagsList.isEmpty ? Html .tags : widget.tagsList,
197187 );
198188 }
199189}
200-
201- class SelectableHtml extends StatefulWidget {
202- /// The `SelectableHtml` widget takes HTML as input and displays a RichText
203- /// tree of the parsed HTML content (which is selectable)
204- ///
205- /// **Attributes**
206- /// **data** *required* takes in a String of HTML data (required only for `Html` constructor).
207- /// **documentElement** *required* takes in a Element of HTML data (required only for `Html.fromDom` and `Html.fromElement` constructor).
208- ///
209- /// **onLinkTap** This function is called whenever a link (`<a href>` )
210- /// is tapped.
211- ///
212- /// **onAnchorTap** This function is called whenever an anchor (#anchor-id)
213- /// is tapped.
214- ///
215- /// **tagsList** Tag names in this array will be the only tags rendered. By default, all tags that support selectable content are rendered.
216- ///
217- /// **style** Pass in the style information for the Html here.
218- /// See [its wiki page] (https://github.com/Sub6Resources/flutter_html/wiki/Style) for more info.
219- ///
220- /// **PLEASE NOTE**
221- ///
222- /// There are a few caveats due to Flutter [#38474] (https://github.com/flutter/flutter/issues/38474):
223- ///
224- /// 1. The list of tags that can be rendered is significantly reduced.
225- /// Key omissions include no support for images/video/audio, table, and ul/ol because they all require widgets and `WidgetSpan` s.
226- ///
227- /// 2. No support for `customRender` , `customImageRender` , `onImageError` , `onImageTap` , `onMathError` , and `navigationDelegateForIframe` .
228- ///
229- /// 3. Styling support is significantly reduced. Only text-related styling works
230- /// (e.g. bold or italic), while container related styling (e.g. borders or padding/margin)
231- /// do not work because we can't use the `ContainerSpan` class (it needs an enclosing `WidgetSpan` ).
232-
233- SelectableHtml ({
234- Key ? key,
235- GlobalKey ? anchorKey,
236- required this .data,
237- this .onLinkTap,
238- this .onAnchorTap,
239- this .onCssParseError,
240- this .shrinkWrap = false ,
241- this .style = const {},
242- this .customRenders = const {},
243- this .tagsList = const [],
244- this .selectionControls,
245- this .scrollPhysics,
246- }) : documentElement = null ,
247- assert (data != null ),
248- _anchorKey = anchorKey ?? GlobalKey (),
249- super (key: key);
250-
251- SelectableHtml .fromDom ({
252- Key ? key,
253- GlobalKey ? anchorKey,
254- @required dom.Document ? document,
255- this .onLinkTap,
256- this .onAnchorTap,
257- this .onCssParseError,
258- this .shrinkWrap = false ,
259- this .style = const {},
260- this .customRenders = const {},
261- this .tagsList = const [],
262- this .selectionControls,
263- this .scrollPhysics,
264- }) : data = null ,
265- assert (document != null ),
266- documentElement = document! .documentElement,
267- _anchorKey = anchorKey ?? GlobalKey (),
268- super (key: key);
269-
270- SelectableHtml .fromElement ({
271- Key ? key,
272- GlobalKey ? anchorKey,
273- @required this .documentElement,
274- this .onLinkTap,
275- this .onAnchorTap,
276- this .onCssParseError,
277- this .shrinkWrap = false ,
278- this .style = const {},
279- this .customRenders = const {},
280- this .tagsList = const [],
281- this .selectionControls,
282- this .scrollPhysics,
283- }) : data = null ,
284- assert (documentElement != null ),
285- _anchorKey = anchorKey ?? GlobalKey (),
286- super (key: key);
287-
288- /// A unique key for this Html widget to ensure uniqueness of anchors
289- final GlobalKey _anchorKey;
290-
291- /// The HTML data passed to the widget as a String
292- final String ? data;
293-
294- /// The HTML data passed to the widget as a pre-processed [dom.Element]
295- final dom.Element ? documentElement;
296-
297- /// A function that defines what to do when a link is tapped
298- final OnTap ? onLinkTap;
299-
300- /// A function that defines what to do when an anchor link is tapped. When this value is set,
301- /// the default anchor behaviour is overwritten.
302- final OnTap ? onAnchorTap;
303-
304- /// A function that defines what to do when CSS fails to parse
305- final OnCssParseError ? onCssParseError;
306-
307- /// A parameter that should be set when the HTML widget is expected to be
308- /// have a flexible width, that doesn't always fill its maximum width
309- /// constraints. For example, auto horizontal margins are ignored, and
310- /// block-level elements only take up the width they need.
311- final bool shrinkWrap;
312-
313- /// A list of HTML tags that are the only tags that are rendered. By default, this list is empty and all supported HTML tags are rendered.
314- final List <String > tagsList;
315-
316- /// An API that allows you to override the default style for any HTML element
317- final Map <String , Style > style;
318-
319- /// Custom Selection controls allows you to override default toolbar and build custom toolbar
320- /// options
321- final TextSelectionControls ? selectionControls;
322-
323- /// Allows you to override the default scrollPhysics for [SelectableText.rich]
324- final ScrollPhysics ? scrollPhysics;
325-
326- /// Either return a custom widget for specific node types or return null to
327- /// fallback to the default rendering.
328- final Map <CustomRenderMatcher , SelectableCustomRender > customRenders;
329-
330- static List <String > get tags =>
331- List <String >.from (HtmlElements .selectableElements);
332-
333- @override
334- State <StatefulWidget > createState () => _SelectableHtmlState ();
335- }
336-
337- class _SelectableHtmlState extends State <SelectableHtml > {
338- late dom.Element documentElement;
339-
340- @override
341- void initState () {
342- super .initState ();
343- documentElement = widget.data != null
344- ? HtmlParser .parseHTML (widget.data! )
345- : widget.documentElement! ;
346- }
347- @override
348- void didUpdateWidget (SelectableHtml oldWidget) {
349- super .didUpdateWidget (oldWidget);
350- if ((widget.data != null && oldWidget.data != widget.data) ||
351- oldWidget.documentElement != widget.documentElement) {
352- documentElement = widget.data != null
353- ? HtmlParser .parseHTML (widget.data! )
354- : widget.documentElement! ;
355- }
356- }
357-
358- @override
359- Widget build (BuildContext context) {
360- return SizedBox (
361- width: widget.shrinkWrap ? null : MediaQuery .of (context).size.width,
362- child: HtmlParser (
363- key: widget._anchorKey,
364- htmlData: documentElement,
365- onLinkTap: widget.onLinkTap,
366- onAnchorTap: widget.onAnchorTap,
367- onImageTap: null ,
368- onCssParseError: widget.onCssParseError,
369- onImageError: null ,
370- shrinkWrap: widget.shrinkWrap,
371- selectable: true ,
372- style: widget.style,
373- customRenders: {}
374- ..addAll (widget.customRenders)
375- ..addAll (generateDefaultRenders ()),
376- tagsList:
377- widget.tagsList.isEmpty ? SelectableHtml .tags : widget.tagsList,
378- selectionControls: widget.selectionControls,
379- scrollPhysics: widget.scrollPhysics,
380- ),
381- );
382- }
383- }
0 commit comments