Sub6Resources / flutter_html

A Flutter widget for rendering static html as Flutter widgets (Will render over 80 different html tags!)
https://pub.dev/packages/flutter_html
MIT License
1.79k stars 860 forks source link

[BUG] TagsWrapExtension fails when there is more than one present #1307

Open Sembauke opened 1 year ago

Sembauke commented 1 year ago

TagsWrapExtension fails when there is more than one present in the extension array.

Sembauke commented 1 year ago

The behaviour seems very flaky when multiple extensions are present.

Nirajn2311 commented 1 year ago

Extending on this. If we add a wrap extension for table element along with TableHtmlExtension then it disables(or more accurately doesn't use the wrapper) the custom table wrapper we created. Now here's the weird part as this happens if TableHtmlExtension is in the list earlier but if it appears later then it works.

Sub6Resources commented 1 year ago

Yeah the significance of ordering could be better documented, and the API could probably be improved further.

Basically, extensions are evaluated in-order, starting with the provided list of extensions and then going through the built-in extensions, stopping after the first element that matches. This means that if one extension matches a tag, then future extensions won't be run for that element by default. This is ideal for use cases like redefining tags, where we don't want the built in extension for that tag to undo any work done by previous extensions or do unnecessary work that won't ever get seen.

The TagWrapExtension explicitly calls prepareFromExtension and buildFromExtension (in the HtmlParser object which is available in the RenderContext) which goes back through the list of extensions (including built-in extensions), and continues processing so that the tag being wrapped is rendered using the built-in extension that originally implemented it.

Can you give some examples of conflict or clashes you've seen in your own extension usage? This will help improve the API if we can get a sense for common use cases.

Additionally, if you have any other suggestions on this API, I'd be happy to hear those too!

Sembauke commented 1 year ago

Hey @Sub6Resources,

Basically, extensions are evaluated in-order, starting with the provided list of extensions and then going through the built-in extensions, stopping after the first element that matches. This means that if one extension matches a tag, then future extensions won't be run for that element by default.

This sounds like good behaviour to me. But it does not seem to work correctly with our way of handling things. Currently we have two TagWrapExtension classes. One is for table and the other is for blockqoute. When disabling the widget for table the blockqoute class seems to work again.

Here I will share with you our extension list, and see if you find any use cases you haven't thought of: https://pastebin.com/aLhnsnMP