Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add more optional stylings #23

Conversation

wwwdata
Copy link
Contributor

@wwwdata wwwdata commented Sep 11, 2018

Hi, thanks for this awesome flutter package. It really helps us a lot to display HTML pages.

However I needed a couple more customisation options. A callback to render a custom Image widget is very useful to be able to apply stylings (rounded borders) or to add network headers and so on.

Apart from that I wanted to apply some specific text paddings and styles.

I also put the print call into an assert block so that this is not constantly logging in a production environment. But for dev, it totally make sense.

@Sub6Resources
Copy link
Owner

Thanks for the pull request. I'll take a look at this soon!

@Sub6Resources
Copy link
Owner

I like the direction this pull request is going, however I think it could be abstracted out a bit more. Let me address each of the changes you have made individually:

networkImagecallback:

Rather than having a specific callback for the img tag, I think a similar callback (proposed in #2) should be called for every tag allowing any tag to be overridden with custom styles and widgets. (#2 gives some general examples of what this callback may look like)

Text padding and styles:

It definitely makes sense to be able to add custom padding/styles to text elements, but adding those attributes to every element would add a whole lot of unnecessary complexity to the parser file. I think a separate HtmlStyles class that holds each of those attributes would be an appropriate way to separate the style data from the html tree data.

print in assert block:

Yeah, you're right, that shouldn't be logging in production. Thanks for catching that.

The callback for customizing a tag's widget will probably be added by me before 0.8.0, so you'll probably have to refactor when I do that.

For the sake of this pull request, If you remove the networkImage callback and move the style properties to a separate class that contains all style properties, I'll gladly merge this. Thanks!

@wwwdata
Copy link
Contributor Author

wwwdata commented Sep 12, 2018

Thanks for your fast and good feedback. I totally agree that a callback that is suggested in #2 would be very awesome. If we add this callback, I think there is no more need to set all different styles manually for elements, right? We could just provide this callback for all nodes. You can then render your custom widget and get passed along children which would be a List<Widget> because in the parser, it gets piped into _parseNodeList which returns the parsed widgets.

The only need to have additional padding/textstyle would be for the else case in the end when we have the final plain text node I guess.

So in the parser, we would always first try to call the callback and see if that returns a custom widget and pass _parseNodeList(node.nodes) in there as children, or, if it does not return a custom widget implementation, fallback to the built in one, so everything is as it was before.

What would be the best mechanism to tell the library that the user did not implement a custom widget for a specific tag? Just returning null instead of a widget maybe?

It could then work somehow like this in the parser:

final CustomWidget customWidget = customWidgetCallback(node.localName);
if (customWidget != null) {
  return customWidget(children: _parseNodeList(node.nodes));
} else {
  switch (node.localName) {
    .....
  }
}

@wwwdata
Copy link
Contributor Author

wwwdata commented Sep 12, 2018

I guess we will also need the node itself in the callback for cases where there are no further parsed widgets down the tree like the img tag. Then you can also access all attributes like css classes if needed and all should work. I will try to do this and see if it works or I forgot to think about something

- It is now possible to render any dom.Node with a custom renderer if
necessary.
- The fallback is the default rendering like before.
@wwwdata
Copy link
Contributor Author

wwwdata commented Sep 12, 2018

Ok, I pushed my changes. This is working really well for me. Having access to the full dom.Node is nice if you need things like css classes and then on certain classes want to use a different styling for elements. Maybe we should also explain this in the Readme then if you want to merge this in?

I guess once this is merged #2 is resolved, right?

@Sub6Resources
Copy link
Owner

Yeah this will fix #2. This looks good. I'll test this a little later today and then work on publishing the changes in a new version. Thanks!

@Sub6Resources
Copy link
Owner

@wwwdata Sorry, it's taken me awhile to get to this. One question: Is there any reason we couldn't use a dom.Element instead of a dom.Node? Being able to use the localName of the element without having to import the html library in order to cast would make it a bit more convenient.

@wwwdata
Copy link
Contributor Author

wwwdata commented Sep 15, 2018

I used dom.Node because I also wanted to modify the dom.Text nodes and use some custom padding around text without padding around everything else. I guess we should stick with dom.Node because then you have maximum flexibility.

@Sub6Resources
Copy link
Owner

Sorry it has taken me so long to get to this again. I agree that using dom.Node is the best option. I'm merging this and will work on publishing it right away.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants