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

Nested inline style configuration question #136

Open
3 tasks done
drxcheng opened this issue Nov 24, 2020 · 3 comments
Open
3 tasks done

Nested inline style configuration question #136

drxcheng opened this issue Nov 24, 2020 · 3 comments
Labels
enhancement New feature or request
Milestone

Comments

@drxcheng
Copy link

  • In the https://www.draftail.org/ documentation I searched for: nested inline style.
  • In the issues / pull requests, I searched for: nested inline style
  • In Stack Overflow, I searched for: draftjs exporter nested inline style

I have this block

            {
                "key": "",
                "text": "Bold Italic Underline",
                "type": "unstyled",
                "depth": 0,
                "inlineStyleRanges": [
                    {"offset": 0, "length": 21, "style": "BOLD"},
                    {"offset": 5, "length": 16, "style": "ITALIC"},
                    {"offset": 12, "length": 9, "style": "UNDERLINE"},
                ],
                "entityRanges": [],
                "data": {},
            },

I expect it to render HTML as

<p><strong>Bold <em>Italic <u>Underline</u></em></strong></p>

but it renders HTML as

<p><strong>Bold </strong><strong><em>Italic </em></strong><strong><em><u>Underline</u></em></strong></p>

Is it a bug or is there any configuration?

@drxcheng drxcheng added the question Further information is requested label Nov 24, 2020
@thibaudcolas
Copy link
Collaborator

Hey @drxcheng, good question. This is how the exporter is intended to work, is this output causing any issues for you?

I haven’t looked at this in a while but from what I recall the current implementation is because Draft.js allows inline style ranges to partially overlap, so converting style ranges to HTML can’t be as simple as mapping single ranges to single tags. For example in a case like:

{
      "text": "Bold Both Italic",
      "type": "unstyled",
      "inlineStyleRanges": [
        {
          "offset": 0,
          "length": 10,
          "style": "BOLD"
        },
        {
          "offset": 5,
          "length": 11,
          "style": "ITALIC"
        }
      ]
    }

This is even more important when style ranges overlap with entity ranges, since a given entity should always map to a single HTML tag – so style tags have to be split like the exporter does. The case you provide where we could shorten the output didn’t feel worthwhile to implement differently.

@drxcheng
Copy link
Author

drxcheng commented Dec 2, 2020

Thanks for the reply. It is currently causing me some minor issue because another library (https://github.com/niuware/mui-rte) behaves differently. I honestly don't know what's the expected behaviour. Feel free to close the ticket if you think it's not an issue.

@thibaudcolas thibaudcolas added enhancement New feature or request and removed question Further information is requested labels Jan 6, 2021
@thibaudcolas
Copy link
Collaborator

👍 thank you for the extra details. I think it would be cool to change the implementation to use the representation you suggest when the ranges are strictly nested rather than overlapping, since admittedly the HTML is much more elegant like that.

I’m not entirely sure how much work that would be so won’t commit to it myself for now, but for future reference the logic is around here:

if style_state:
styled_node = style_state.render_styles(
decorated_node, block, wrapper_state.blocks
)
else:
styled_node = decorated_node
entity_node = entity_state.render_entities(
styled_node, block, wrapper_state.blocks
)

Commentary mostly for my future benefit: style_state.render_styles is where the style tags are created "early" – the logic is to create all of the tags currently applied, every time a new tag is encountered. We’d need to change that to "only render when the closing tag is to be reached". One of the likely issues is that this "only render when closing is reached" is what the entity_state does… keeping the stack of elements along the way. So it might be "simplest" to combine style and entity state into a single "inline state", so the stack of inline elements is shared. Just with different logic between style and entities to resolve overlaps.

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

No branches or pull requests

2 participants