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

property styles #367

Closed
misterfourtytwo opened this issue Nov 5, 2020 · 15 comments
Closed

property styles #367

misterfourtytwo opened this issue Nov 5, 2020 · 15 comments
Assignees
Labels
question Further information is requested

Comments

@misterfourtytwo
Copy link

would be real nice to add property styles to element in custom styles builder so people won't need to write smth like this every time they need to parse style properties

          final List<String> l = e?.attributes['style']
                  ?.replaceAll(RegExp(r'(\s)+'), '')
                  ?.split(';') ??
              <String>[];

          final Map<String, String> styles = <String, String>{};
          for (final String keyValue
              in l.where((String value) => value?.contains(':') == true)) {
            final List<String> pair =
                keyValue.replaceAll(RegExp(r'([\s]+)'), ' ').split(':');
            styles[pair[0]] = pair[1];
          }
@daohoangson
Copy link
Owner

Why do you need to parse the styles atttibute in customStylesBuilder? The package automatically parses those and apply to the element by itself already...

@daohoangson daohoangson self-assigned this Nov 5, 2020
@daohoangson daohoangson added the question Further information is requested label Nov 5, 2020
@misterfourtytwo
Copy link
Author

when i need to apply changes to incoming styles.
i.e. there is a company site, api sends some page parts to render in app, but i need to change some styling

@daohoangson
Copy link
Owner

Ah I see, it's possible we will make the parsed key-value pairs available during customStylesBuilder for your use case.

@daohoangson daohoangson added enhancement New feature or request and removed question Further information is requested labels Nov 7, 2020
daohoangson added a commit that referenced this issue Nov 17, 2020
Making it easier for users of this package to handle inline styles
and/or customize rendering behaviors.

Related to #367
@daohoangson daohoangson added this to the 0.5.2 milestone Nov 27, 2020
daohoangson added a commit that referenced this issue Jan 18, 2021
Making it easier for users of this package to handle inline styles
and/or customize rendering behaviors.

Related to #367
@daohoangson
Copy link
Owner

Version 0.5.2 has been released with support for this. It is now straightforward to get the list of inline styles:

import 'package:flutter_widget_from_html/flutter_widget_from_html.dart';

/// in your `WidgetFactory` or `BuildOp`
for (final style in meta.element.styles) {
  print('${style.key}=${style.value}');
}

Please try upgrading and let me know whether it works for you. Thank you.

@daohoangson daohoangson added question Further information is requested and removed enhancement New feature or request labels Feb 15, 2021
@misterfourtytwo
Copy link
Author

as far as i understand i cannot use this in the custom styles builder?

@daohoangson
Copy link
Owner

No problem, you can use it in customStylesBuilder. Something like this:

          HtmlWidget(
            html,
            customStylesBuilder: (element) {
              for (final style in element.styles) {
                if (style.key == 'foo') {
                  return {'foo': 'bar'};
                }
              }

              return null;
            },
          ),

@misterfourtytwo
Copy link
Author

so, you can see that my app has last plugin version locked:
image

and debugger seem not to see this field
image

@daohoangson
Copy link
Owner

It is not a field, it is an extension. Does your print() statement work?

@misterfourtytwo
Copy link
Author

as i'm saying, nope.
if this is an extension, then i probably must import it separately and this solves the mystery why analyzer doesn't see it.
could u please specify where it is located so i could test with it inluded in file?

@daohoangson
Copy link
Owner

daohoangson commented Feb 22, 2021

import 'package:flutter_widget_from_html/flutter_widget_from_html.dart';

That should be enough. If you follow that import, it will export 'src/helpers.dart'; then export 'package:flutter_widget_from_html_core/src/core_helpers.dart';. You should be able to find DomElementExtension there.

@misterfourtytwo
Copy link
Author

misterfourtytwo commented Feb 25, 2021

sorry for the delay, got busy lately.
class extension is certainly there, but my project doesn't seem to connect it, even after explicitly importing extension and specifying element type.
image
when instead of prefixing type i use hide element on 'package:flutter/foundation.dart', i get following
image
though, without 'package:html/dom.dart' import analyzer can not find Element type.
my guess is that there is some bug in analyzer/linter, which does not allow to properly import extensions from external package, but inside one everything works properly.
switched and tested on the master flutter branch, instead of stable, got the same behavior.

@daohoangson
Copy link
Owner

I think I have figured it out.

In the first version of your code, you used customStylesBuilder: (dynamic e) {}. The dynamic type basically disabled the extension method since extension is resolved at compile time. Then you specified Element type but that didn't work because of a name conflict. You have to follow the suggestion to import 'package:html/dom.dart' as dom; then use customStylesBuilder: (dom.Element e) {}.

It's possible to skip the typing completely, using customStylesBuilder: (e) {} is simple and should be enough.

@daohoangson daohoangson removed this from the 0.5.2 milestone Feb 27, 2021
@misterfourtytwo
Copy link
Author

misterfourtytwo commented Feb 27, 2021

nope, using import as dom was the first thing i did.
ill check this on my linux machine and later recheck on mac.
if one does not cast type and specify dynamic, you could still see full object type in debugger and it hadn't imported extension for me.
unfortunately, linter rules of my app do not allow to run without specified arguments types. ill also check this without them to narrow down problem cases.
upd. checked on linux, both your solutions seem to work fine. maybe its an engine or low memory bug on macos when it does not import extension.

@daohoangson
Copy link
Owner

I have just revisited this with Flutter 2 and it seems to work fine.

import 'package:flutter/material.dart';
import 'package:flutter_widget_from_html/flutter_widget_from_html.dart';
import 'package:html/dom.dart' as dom;

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      home: MyHomePage(),
    );
  }
}

class MyHomePage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Issue 367'),
      ),
      body: HtmlWidget(
        'Foo',
        customStylesBuilder: (dom.Element element) {
          for (final style in element.styles) {
            if (style.key == 'foo') {
              return {'foo': 'bar'};
            }
          }

          return null;
        },
      ),
    );
  }
}

@misterfourtytwo
Copy link
Author

misterfourtytwo commented Apr 2, 2021

Yeah, on 2.0 seems to be working fine with either of dynamic, dom.Element and simply Element(imported from flutter_widget_from_html, when hidden imports from other packages.)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
question Further information is requested
Projects
None yet
Development

No branches or pull requests

2 participants