Do you want to request a _feature_ or report a _bug_?
Report a bug.
What is the current behavior?
The convertFromHTML() method strips inline style attribute from HTML strings.
When importing this HTML string (via convertFromHTML()):
"<p>This is some <span style="color: #f0ad4e">colorful</span> text.</p>"
The line is converted to this:
"<p>This is some colorful text.</p>"
What is the expected behavior?
Keep inline style attribute when using convertFromHTML()
Which versions of Draft.js, and which browser / OS are affected by this issue? Did this work in previous versions of Draft.js?
Draft JS v0.8.1 running in Chrome
Just to elaborate, we want to replace our old RTE with Draft, but I think this may be too much of an issue to move forward, since our database returns content in HTML string format. I'm not sure why Draft doesn't offer the ability to convert inline CSS style to it's own native style format, but it seems like it would be absolutely necessary in order to integrate with existing projects and databases. Doesn't this severely limit the use case for Draft? I mean, unless you are storing Draft ContentBlocks in your database, how would you be able to use a Draft editor to edit existing content?
You can provide your own function for converting HTML to Draft, see for example https://github.com/sstur/draft-js-import-html. You can also use such a function when pasting html into the editor: http://facebook.github.io/draft-js/docs/api-reference-editor.html#handlepastedtext.
@robbertbrak
Thanks for the reply.
I have tried using the draft-js-import-html package. As far as I can tell it has the same behavior as the native convertFromHTML method in that it strips away any inline style I add (same way as I mentioned above). I am using the draft-js-export-html package to export HTML strings, and that works to preserve the inline style, but when I try to import the HTML string, the style is stripped away.
The reason it does that is because these converters don't know how to interpret your custom style attributes. Draft itself doesn't use HTML as internal representation; it knows only about block types, inline styles and entities.
The Draft Way would therefore be to parse the HTML yourself and transform any HTML attributes you care about to inline styles or entities.
Note that this can be quite a tough challenge, because HTML can be almost arbitrarily nested, whereas the Draft Block structure is basically flat. For my own project (not open-source unfortunately) I wrote my own converter, but you may be able to adjust the draft-js-import-html to your liking.
Looks like I will have to figure out some sort of workaround. Thanks for the info @robbertbrak!
Hi !
I am facing the exact same issue right now. All my styles are stripped off when I load the same content from DB, the same content has all the styles in the returned HTML but converFromHTML strips off everything.
Please let me know if anybody has figured out a solution for this.
Thanks.
What I don't quite understand is that this seems to be a WYSIWYG editor for using on a web page, but it doesn't quite have an easy way built in to convert the rich text to/from HTML (even though it appears to be doing it internally for displaying within the editor window itself)... why not just expose those methods? why only expose convertFromHtml()? Is the idea that you would just convertToRaw() then JSON.stringify() that into your database? Then JSON.parse() that back to JS to dump back into the editor and/or render to your desired format?
I chose this solution, because I thought it might play nicely as an editor for generating content for a React Native app I'm building. I started out building a component to convert HTML to nested draft-js-export-html but as mentioned above, also ran into the issue of the inline styles being stripped when using either convertFromHtml() or draft-js-import-html (even when passing the same export options to import, in the case of draft-js-import-html).
I then thought, ok, well maybe I need to use the raw blocks to render directly to React Native components instead of using HTML as a go between and storage mechanism... which led me to react-native-draftjs-render, which I'm unable to even try because their import immediately breaks my web app...
Any suggestions on where to go from here? I just want a way to create content in a WYSIWYG editor, save that to a database, then load it up in my react native app. Nothing too fancy like horizontal rules, or links or anything... just plain text, bold, italic, and one custom style where I can change the font-family to another one.... That's actually the most complicated part since I'm trying to use inline styles to define that custom typeface for those spans of text. Do I need to just hack this to use an <em> as my custom typeface and the <i> for italics?
@andersryanc
Hey while using react, it is easy to store the content in the exact same format, including styles. All we need to do is to use editorstatejson for this purpose.
For my blog application, for each blog I save 2 things (concerned right now), editorstatejson and html. In the editor I load editorstatejson for editing and save it as html (which by by default has incline styles). Now I use this HTML to rendor at places.
Have a look at the code block below and pay attention to the if else return part. Here I am restoring content from editorstatejson with styles. createWithContent is an important method
componentDidMount(){
let data = JSON.stringify({ blogKey: this.state.blogKey })
axios.post('http://localhost:3500/ftchSvdBlgCntnt', data, {
headers: {'Content-Type': 'application/json'}
})
.then((response) => {
if(response.data[0].editorstatejson){
this.setState({ editorState: EditorState.createWithContent(convertFromRaw(response.data[0].editorstatejson)) })
}else{
this.setState({ editorState: EditorState.createEmpty() });
}
return EditorState.createWithContent(convertFromRaw(response.data[0].editorstatejson));
})
.catch((error) => {console.log(error)});
}
Hope that helps. Let me know if anything is unclear.
every damn thing in universe is unclear
For everyone still looking for a solution, this converter, from Draftail, provides callbacks to customize the creation of entities, given an HTML node. So you can manually access those inline-styles, and add them as data to your entity:
For example:
import { convertFromHTML } from 'draft-convert';
convertFromHTML({
htmlToEntity: (nodeName, node, createEntity) => {
if (nodeName === 'img') {
const entityConfig = {};
entityConfig.src = node.getAttribute ? node.getAttribute('src') || node.src : node.src;
entityConfig.alt = node.alt;
entityConfig.height = node.style.height;
entityConfig.width = node.style.width;
return createEntity(
'IMAGE',
'MUTABLE',
entityConfig,
);
}
}
});
This code worked for me(particularly lines 12-16) when I wanted to convert HTML as a string to draftjs data and load it in the editor's state without stripping the HTML attributes:
import htmlToDraft from 'html-to-draftjs';
const contentBlock = htmlToDraft(htmlString);
const contentState = ContentState.createFromBlockArray(contentBlock.contentBlocks);
const editorState = EditorState.createWithContent(contentState);
https://github.com/jpuri/react-draft-wysiwyg/blob/master/stories/ConvertFromHTML/index.js
@AkyunaAkish Saved my life! Thank you
@AkyunaAkish Actually its not working for my case. I want to convert my html into draft state. with same styling properties. I tried lot of methods but got nothing.
@AkyunaAkish you save me
This code worked for me(particularly lines 12-16) when I wanted to convert HTML as a string to draftjs data and load it in the editor's state without stripping the HTML attributes:
import htmlToDraft from 'html-to-draftjs'; const contentBlock = htmlToDraft(htmlString); const contentState = ContentState.createFromBlockArray(contentBlock.contentBlocks); const editorState = EditorState.createWithContent(contentState);https://github.com/jpuri/react-draft-wysiwyg/blob/master/stories/ConvertFromHTML/index.js
thanks bro, you save my ass lol
This code worked for me(particularly lines 12-16) when I wanted to convert HTML as a string to draftjs data and load it in the editor's state without stripping the HTML attributes:
import htmlToDraft from 'html-to-draftjs'; const contentBlock = htmlToDraft(htmlString); const contentState = ContentState.createFromBlockArray(contentBlock.contentBlocks); const editorState = EditorState.createWithContent(contentState);https://github.com/jpuri/react-draft-wysiwyg/blob/master/stories/ConvertFromHTML/index.js
This solution works for HTML, but not for HTML with inline styles :'(
Any solution?
@ademars94 Do you find any solution for your problem?
Any solution guys?
Hello guys
In the below Code,
import htmlToDraft from "html-to-draftjs";
import { ContentState, EditorState } from "draft-js";
const blocksFromHTML = htmlToDraft(data.notes);
const contentState = ContentState.createFromBlockArray(
blocksFromHTML.contentBlocks,
blocksFromHTML.entityMap
);
const editorState = EditorState.createWithContent(contentState);
In the below Code,
import { ContentState, convertFromHTML, EditorState } from "draft-js";
const blocksFromHTML = convertFromHTML(data.notes);
const contentState = ContentState.createFromBlockArray(
blocksFromHTML.contentBlocks,
blocksFromHTML.entityMap
);
const editorState = EditorState.createWithContent(contentState);
Does anyone have a solution where all the above 3 will work fine??
Most helpful comment
This code worked for me(particularly lines 12-16) when I wanted to convert HTML as a string to draftjs data and load it in the editor's state without stripping the HTML attributes:
https://github.com/jpuri/react-draft-wysiwyg/blob/master/stories/ConvertFromHTML/index.js