hubspot / draft-convert Goto Github PK
View Code? Open in Web Editor NEWExtensibly serialize & deserialize Draft.js ContentState with HTML.
License: Apache License 2.0
Extensibly serialize & deserialize Draft.js ContentState with HTML.
License: Apache License 2.0
Hi guys
Having "text": " " in a block (Empty space in the value), makes convertToHTML method return empty on version 1.4.9.
Example block data below:
{
"data" : {},
"entityRanges" : [
{
"key" : 0,
"length" : 1,
"offset" : 0
}
],
"inlineStyleRanges" : [],
"depth" : 0,
"type" : "unstyled",
"text" : " ",
"key" : "6k1g"
},
This didn't happen on prior versions.
Any ideas?
Content copied from Apple Notes may contain <style>
elements. These elements should be completely ignore but I can't find a wait to do it.
Am I missing something?
A solution to add that to the API would be to ignore the element if htmlToBlock
returns false
.
Invariant Violation: convertToHTML: received block information without either a ReactElement or an object with start/end tags
at invariant (/project/node_modules/invariant/invariant.js:42:15)
at getNestedBlockTags (/project/node_modules/draft-convert/lib/util/getNestedBlockTags.js:37:27)
at /project/node_modules/draft-convert/lib/convertToHTML.js:111:64
at Array.map (native)
at /project/node_modules/draft-convert/lib/convertToHTML.js:83:34
This happens whenever there's an ordered or unordered list. Adding the block types to the blockToHTML function has no effect. It still throws that error.
Since Draft.js only supports bold, italics, underline, code, and strikethrough natively, I've been trying to add subcript and superscript as well.
This seems like what I'm looking for, but so far I haven't gotten things to work.
This is what <sub>subscript</sub> and <sup>superscript</sup> tags look like
[email protected]
includes the new way to use entities, which draft-convert
will need to support.
While using convertFromHTML
, in htmlToEntity
method, we need to use Entity.create
to create one draft entity. But console report a warning that "DraftEntity.create will be deprecated soon!" and suggest use contentState.createEntity
instead.
Question is that there is no contentState yet at the moment... Any solution or workaround ?
Hi community,
When I call convertToHtml
on ContentState
it works only if no <img>
tag is present (or better to say that no 'IMAGE' entity is present inside the blocks).
If the IMAGE
entity is present, I get the above error. A console screenshot is attached below :
I'm calling the following function to generate html.
getInnerHtml() {
return convertToHTML({
entityToHTML: (entity, originalText) => {
if (entity.type === 'IMAGE') {
return `<span><img src='${entity.data.src}' /></span>`;
}
return originalText;
}
})(this.state.editorState.getCurrentContent());
}
How to go about this ?
I have the following versions of relavent packages.
"draft-convert": "^1.4.2",
"draft-js": "^0.10.0",
"react": "^15.3.2",
"react-dom": "^15.3.2",
on Chrome 56 on Macbook AIR.
#30 is a similar issue but doesn't solves my problem.
Thanks.
Hello. I was trying to use draft-convert to transform HTML to content when user paste text.
Here is my current code:
class Draft extends Component {
pasteText(text, html) {
const editorState = this.getter();
const blockMap = convertFromHTML(config)(html).blockMap;
const newState = Modifier.replaceWithFragment(
editorState.getCurrentContent(),
editorState.getSelection(),
blockMap
);
this.setter(EditorState.push(editorState, newState, 'insert-fragment'));
return false;
}
render() {
return (
<div className="">
<Editor
handlePastedText={(text, html) => this.pasteText(text, html)}
/>
</div>
);
}
}
const config = {
htmlToBlock: (nodeName, node) => {},
htmlToStyle: (nodeName, node, currentStyle) => currentStyle,
htmlToEntity: (nodeName, node, createEntity) => {
if (nodeName === 'img' && node.getAttribute('data-image-id')) {
return createEntity('image', 'IMMUTABLE', { src: node.src );
}
// In the case this is pasted image (it has not attribute 'data-image-id') I just return null
else if (nodeName === 'img') {
return null
}
},
textToEntity: (text, createEntity) => {}
}
As you can see, I try to return null if this is pasted image. But it doesn't works. As the result I got π· symbol instead of images.
How can I handle this? Maybe there is some way to escape this symbol?
html:
<ul><li>123<br />456</li></ul>
result in flat mode:
should be:
I'm trying to implement an isomorphic render, including Draft.js + draft-convert. Client-side works fine, but I'm facing a problem on server-side.
/src/utils/parseHTML.js
contains a function fallback()
which using document
. Of course there is no document
when you on server-side, so the question is β how to avoid that problem?
Hey Guys,
I'm using the convertToHTML
method and I managed to get stuck into an endless loop with it, that crashes the browser. Just wanted you to be aware of it.
This is how I used it:
import{ convertToHTML } from "draft-convert";
const html = convertToHTML(this.state.editorState.getCurrentContent());
The only special thing I do before calling this method was to initialize Draft.js with a raw document ({blocks: [...], entityMap: {}}
) that I had stored in my DB (contains bulletpoints). Like this:
var jsonFromDB = {blocks: [...], entityMap: {}};
var blocks = convertFromRaw(jsonFromDB);
var editorState = EditorState.createWithContent(
blocks, decorator
);
this.setState({
editorState: editorState,
});
^ like this
Hi,
I couldn't figure out how to do this, but basically whenever a user creates a blank new line in the editor, I want to ignore the output (Block type = unstyled, text = ''), but I can't seem to change the block output to be null or ''. I've resorted to using for now, but would love to get rid of the hack.
Thanks!
I'm using convertFromHTML and convertToHTML as documented in the README, but the resulting EditorState and HTML, respectively, seem to remove any applied inline styles and tags. See screenshots.
The original HTML has a red paragraph:
After running const textState = EditorState.createWithContent(convertFromHTML(defaultText))
where defaultText
is an HTML string, the EditorState in react-draft-wysiwyg doesn't have the red color applied anymore:
So then when using convertToHTML, the result doesn't have the red color attribute either.
Similarly, if I create some colored text or a link in the editor directly, and use convertToHTML, the resulting HTML still doesn't have the text color, and the link tag is removed:
with convertToHTML(snakeCaseEditors.registration_form_html.getCurrentContent())
results in <p>...We invite you to register to join our...</p>
As far as I can tell, react-draft-wysiwyg isn't doing anything strange with EditorState. Am I missing some configuration? I'm not trying to do any custom formatting, just trying to maintain integrity through the conversion.
draft-convert 1.4.3
draft-js 0.10.0
react-draft-wysiwyg 1.9.4
Do I need to use middleware function for this? If yes, can you please give me simple example of using it?
Function convertFromHTML() don't correctly work with content of tag "blockquote"
In my editor, when you add an image. It adds placeholder text like {{image}}
and applies an immutable entity to that with the url
set to the image URL.
I am converting to HTML like so:
entityToHTML(entity, originalText) {
if (entity.type === 'IMG') {
return <span><img src={entity.data.url} /></span>
}
return originalText
}
Converting to HTML works great.
However when I convert back FROM html it is not adding the original text back:
htmlToEntity(nodeName, node) {
if (nodeName === 'img') {
return Entity.create(
'IMG',
'IMMUTABLE',
{ url: node.src }
)
}
}
It seems like htmlToEntity
gets back the entityID
and then applies to the the content of the node
that produced it. However bc the img
is a void element and has not content, no content gets added back to the editor to apply the entity to.
Maybe it might make sense that if htmlToEntity
returns an object with key
and originalText
it uses the key
as the entity key and the originalText
as the content instead of the content of the node
.
Assuming I have such an entityToHTML
entityToHTML: (entity, originalText) => {
if(entity.type === "IMAGE") {
return (
<img src={entity.data.src} style={{width: "100%"}}/>
)
}
}
It goes to the https://github.com/HubSpot/draft-convert/blob/master/src/blockEntities.js#L34 to get tag element length:
const entityHTML = getEntityHTML(entity, originalText);
const converted = [...getElementHTML(entityHTML, originalText)
|| originalText];
const prefixLength = getElementTagLength(entityHTML, 'start');
const suffixLength = getElementTagLength(entityHTML, 'end');
The getElementTagLength (https://github.com/HubSpot/draft-convert/blob/master/src/util/getElementTagLength.js#L6) use splitReactElement:
const getElementTagLength = (element, type = 'start') => {
if (React.isValidElement(element)) {
const length = splitReactElement(element)[type].length;
const child = React.Children.toArray(element.props.children)[0];
return length + (child && React.isValidElement(child)
? getElementTagLength(child, type)
: 0
);
}
......
However the splitReactElement than treat the as "void element" (https://github.com/HubSpot/draft-convert/blob/master/src/util/splitReactElement.js#L25) , where it directly returns a String, rather than {start: <sth>, end: <sth>}
:
if (VOID_TAGS.indexOf(element.type) !== -1) {
return ReactDOMServer.renderToStaticMarkup(element);
}
Then the splitReactElement(element)[type].length
report an error.
Isn't it an issue, or am I missing something?
If there is an emoji (with .length >= 2
) before an entity. The entity originalText argument in the entityToHTML
is incorrect. Here's a breaking test:
it('handles offset of entities after an emoji', () => {
const contentState = buildContentState([
{
text: 'π Santi Albo',
type: 'unstyled',
depth: 0,
entityRanges: [{
offset: 0,
length: 1,
key: 0,
}, {
offset: 2,
length: 10,
key: 1,
}],
}
], {
0: {
type: 'emoji',
mutability: 'IMMUTABLE',
data: {
emojiUnicode: 'π'
}
},
1: {
type: 'mention',
mutability: 'SEGMENTED',
data: {
href: '/users/1'
}
}
});
const result = convertToHTML({
entityToHTML(entity, originalText) {
if (entity.type === 'emoji') {
return entity.data.emojiUnicode;
} else if (entity.type === 'mention') {
return <a href={entity.data.href}>{originalText}</a> // <-- originalText here is "anti Albo"
}
}
})(contentState);
// result === '<p>π S<a href="/users/1">anti Albo</a></p>'
expect(result).toBe('<p>π <a href="/users/1">Santi Albo</a></p>');
});
Given the following in convertFromHTML
const newContentState = convertFromHTML({
htmlToStyle: (nodeName, node, currentStyle) => {
console.log(nodeName);
console.log(node);
},
};
I get the following error on console:
convertFromHTML.js?2ed9:202 Uncaught TypeError: Cannot read property 'withMutations' of undefined
at eval (convertFromHTML.js?2ed9:202)
at processInlineTag (convertFromHTML.js?2ed9:219)
at genFragment (convertFromHTML.js?2ed9:359)
at genFragment (convertFromHTML.js?2ed9:427)
at getChunkForHTML (convertFromHTML.js?2ed9:481)
at convertFromHTMLtoContentBlocks (convertFromHTML.js?2ed9:521)
at eval (convertFromHTML.js?2ed9:611)
at EditDocument.handlePastedText (EditDocument.jsx?1364:311)
at editOnPaste (editOnPaste.js?e835:75)
at eval (DraftEditor.react.js?61d6:147)
So I'm saving these variable
entities in my HTML.
I initially load the HTML into my editor using convertFromHTML
, where I use htmlToEntity
to convert that HTML entity into an actual entity by calling Entity.create()
, and then I return that as indicated by the docs.
Now my HTML is loaded into the editor with the entities as desired. But when I go to convertToHTML
on this exact same content state, I get this error:
Invariant Violation: Unknown DraftEntity key.
I put a breakpoint there and the instances
variable is empty.. when it should be full of the entities I imported earlier. What gives?
Unless I'm misinterpreting this, I think it's because your package has its own version of Draft, and Entities are part of the global state within Draft. When loading, I was using my version of Draft, so my Entities are in my global state, but not yours. This doesn't show up in tests because your tests are using the same version of Draft in and out.
This won't be an issue once this is resolved.
The simplest solution I can think of is to allow me to pass in convertToRaw
, so that your package uses my global Draft state instead of yours. What do you think?
Perhaps there is already built in logic for this, but I'm not able to map
tags to paragraph blocks when using the htmlToBlock
function in convertFromHTML
These tags are not being parsed as nodes so wondering if there is a way to achieve this?
When setting a wrapper to the blockRenderMap, draft-js will wrap the block with a custom component.
It will be great if supporting this.
In draft-js docs:
const blockRenderMap = Immutable.Map({
'MyCustomBlock': {
// element is used during paste or html conversion to auto match your component;
// it is also retained as part of this.props.children and not stripped out
element: 'section',
wrapper: <MyCustomBlock {...this.props} />
}
});
Hello! First, great project -- thank you for this @benbriggs etal π―
I'm running into an issue w/convertFromHTML where giving it an atomic block that contains a figcaption is producing some odd output.
What I'm feeding it is, essentially:
// outer figure is draftJS atomic wrapper, inner is React component wrapper
<figure>
<figure>
<img src="foo.png" />
<figcaption>This is an image</figcaption>
</figure>
</figure>
What I'm getting out is:
<figure>
<figure>
<img src="foo.png" />
<figcaption>This is an image</figcaption>
</figure>
This is an image.
</figure>
On each successive import, it will append the "This is an image" string again, so I end up with ...</figure>This is an image.This is an image.This is an image.</figure>
after 3 imports, and so on.
Any ideas what could be going on here? It looks like this line was introduced to fix rendering of nested elements within atomic blocks, but wondering if it shouldn't ignore (inner)text? Or maybe it's something I'm doing/not doing either here or in convertToHTML?
It will be great if supporting React elements, so we can define a parser like
const renderMention = (entity) => {
const { id, username, name } = entity.data.mention
return (
<Link to={`/user/${id}/${username}`}>
{name}
</Link>
)
}
hi, here is my code, i get nothing when i convert to html. But display is fine. here is the same problem(facebookarchive/draft-js#609) Any suggestion? thanks!
import React, { Component } from 'react'
import { Entity, Modifier, EditorState } from 'draft-js'
import { createPlugin, pluginUtils } from 'draft-extend'
import { Button, Modal, message } from 'antd'
import VideoSelect from '../../Resource/Video/Select'
import { videoUrlConvert } from '../../../utils'
const ENTITY_TYPE = 'VIDEO'
// const BLOCK_TYPE = 'atomic'
class VideoButton extends Component {
constructor() {
super()
this.state = {
visible: false,
record: null
}
}
toggleVisible = () => this.setState({ visible: !this.state.visible })
okHandler = () => {
const { record } = this.state
if (record) {
const { editorState, onChange } = this.props
const src = videoUrlConvert(record.path)
if (src === '') {
this.setState({ record : null })
return message.error('θ§ι’ε°εζθ――,θ―·ιζ°ιζ©οΌ')
}
const entityKey = Entity.create(
ENTITY_TYPE,
'IMMUTABLE',
{ src }
)
const contentState = Modifier.insertText(
editorState.getCurrentContent(),
editorState.getSelection(),
'ζ΅θ§ε¨δΈζ―ζ',
null,
entityKey
)
onChange(EditorState.push(editorState, contentState, 'apply-entity'))
this.toggleVisible()
} else {
message.warn('θ―·ιζ©δΈι‘ΉοΌ')
}
}
render() {
const { visible } = this.state
return (
<div>
<Modal
visible={visible}
title="ιζ©θ§ι’"
onOk={this.okHandler}
onCancel={this.toggleVisible}
maskClosable={false}
width={720}
>
<VideoSelect onChange={val => this.setState({ record: val })}/>
</Modal>
<Button onClick={this.toggleVisible}>ζ·»ε θ§ι’</Button>
</div>
)
}
}
const VideoDecorator = {
strategy: pluginUtils.entityStrategy(ENTITY_TYPE),
component: props => {
const entity = Entity.get(props.entityKey)
const { src } = entity.getData()
return (
<iframe allowFullScreen frameBorder={0} width={300} height={200} src={src} controls />
);
}
}
const htmlToEntity = (nodeName, node) => {
if (nodeName === 'iframe') {
return Entity.create(
ENTITY_TYPE,
'IMMUTABLE',
{
src: node.getAttribute('src'),
}
)
}
}
const entityToHTML = (entity, originalText) => {
if (entity.type === ENTITY_TYPE) {
return `<iframe allowfullscreen frameborder=0 width="300" height="200" src="${entity.data.src}" controls>${originalText}</iframe>`
}
return originalText
};
// const blockRendererFn = (block) => {
// if (block.getType() === 'atomic' && block.size > 0 && Entity.get(block.getEntityAt(0)).getType() === ENTITY_TYPE) {
// return {
// component: ({ block }) => {
// const {src} = Entity.get(block.getEntityAt(0)).getData()
// return <iframe allowFullScreen frameBorder={0} width={300} height={200} src={src} controls>ζ΅θ§ε¨δΈζ―ζ</iframe>
// },
// editable: false
// };
// }
// }
const VideoPlugin = createPlugin({
displayName: 'VideoPlugin',
buttons: VideoButton,
decorators: VideoDecorator,
htmlToEntity,
entityToHTML,
// blockRendererFn,
// htmlToBlock: (nodeName) => {
// if (nodeName === 'figure') {
// return BLOCK_TYPE;
// }
// },
// blockToHTML: {
// 'atomic': {
// start: '<figure>',
// end: '</figure>'
// }
// }
});
export default VideoPlugin
Generally, it seems issues and pull requests are not given much attention in this repository. I am not whining, but as a user of this repository, it puts me (and the products I work on) in an awkward spot: should we wait, or create a temporary fork? Or a permanent?
I'd love to keep contributing to this library.
If you do not have a lot of time to maintain the project, would you be willing to take on more maintainers?
Hey,
I've added a custom inline style for coloring some text. Using styleToHTML I create a <span>
with some inline style.
If the same text range also has 'underline' style there is no way to control the processing order of the styles and they are treated in the order they were applied.
This may cause issues as
<span style="color: blue"><u>text</u></span>
and
<u><span style="color: blue">text</span></u>
are different. In the latter case the color style doesn't affect the underline.
I've tried changing the way underlines are treated to create a <span style="text-decoration: underline">
but unfortunately the spans don't merge even if they have the same range so I'm facing the same problem.
Is there a way around this ?
I imagine merging identical tags (and the style attribute) is a possible solution.
Another solution is somehow controlling the style processing order by somehow specifying priority.
A temporary workaround is to remove the underline before I apply a color and then set it again. If the underline is the last added style it's always handled first when the custom HTML is generated, but that feels really hacky.
Thanks
I've found a strange bug where if there are multiple emoji in a single block and they are followed by an apostrophe or quote which has an inline style, the HTML entity for the apostrophe/quote is split by the styling tag (ie <strong>
). This results in text which should be rendered like this:
aaaπ₯π₯a'aa
rendering like this (okay apparently this makes markdown sad but you can imagine that the * rendered as bold):
aaaπ₯π₯**a&#**x27;aa
I haven't had time to dig into this but I did write tests on to demonstrate this bug on this branch. My initial thought was that it was being caused by something in blockInlineStyles
, but as you see if you run the (nearly identical) tests, the one for just blockInlineStyles
passes but the test on convertToHTML
fails.
For an entity that overlaps with a style:
input: Lorem ipsum dolor sit amet, consectetur adipiscing elit.
expected: <a href="http://test.com">Lorem ipsum dolor sit <i>amet</i></a><i>, consectetur adipiscing elit.</i>
actual: <a href="http://test.c<i>om">Lorem ipsum dolor sit amet</a></i>, consectetur adipiscing elit.
For an style that overlaps with an entity:
input: Lorem ipsum dolor sit amet, consectetur adipiscing elit.
expected: <i>Lorem ipsum dolor sit <a href="http://test.com">amet</a></i><a href="http://test.com">, consectetur adipiscing elit.</a>
actual: <a href="http://test.c<i>om">Lorem ipsum dolor sit amet</a></i>, consectetur adipiscing elit.
Seems like this has something to do with prefixLength
and suffixLength
of entities not working correctly.
Allow use of block metadata when converting to or from HTML. Metadata was added in draft-js 0.8.0
I get the following error when I try to use draft-convert
convertToHTML returning an <img>
tag in blockToHTML gives error
Uncaught Error: img is a void element tag and must neither have 'children' nor use 'dangerouslySetInnerHTML'
Here is my function for exporting to html.
export function editorStateToHtml (editorState) {
if (editorState) {
const html = convertToHTML({
styleToHTML: (style) => {
if (style === 'BOLD') {
return <span style={{color: 'blue'}} />;
}
},
blockToHTML: (block) => {
const type = block.type
if (type === 'atomic') {
let url = block.data.src
return <img src={url} />
}
if (type === 'unstyled') {
return <p />
}
},
entityToHTML: (entity, originalText) => {
if (entity.type === 'LINK') {
return <a href={entity.data.url}>{originalText}</a>;
}
return originalText;
}
})(editorState.getCurrentContent());
return html
}
}
Can we expect updated peerDependencies
for the draft-convert project in the near future?
I'am specifically thinking of the react
and react-dom
packages which are both locked to ^15.0.2
. If you can see that the upgrade is working fine, maybe you can change the peerDependencies
to something like ^15.0.2 || ^16.0
.
At the moment, we can not upgrade to React v16 due to the locked version.
Hello, I've just installed this converter and I've found an issue.
How do I prevent single line breaks to being turned into new paragraphs?
Right now writing
Example Text\n
Second Line
gets turned into
<p>Example Text</p><p>Second Line</p>
whereas the result I expect should be
<p>Example Text<br>Second Line</p>
Two consecutive line breaks instead should be turned into a new paragraph.
Any ideas on how I could achieve this?
Is there a way to use the convertToHTML function to get 'code-block' elements that are next to each other to be rendered in one pre tag?
I was able to solve this problem with a different library for converting Draft blocks to html (sstur/draft-js-utils#26) but I haven't been able to figure it out with draft-convert.
I was wondering why a ENTITY_MAP
is used to convert text in entities, here https://github.com/HubSpot/draft-convert/blob/master/src/encodeBlock.js#L4 ?
Because this is what is happening when using a entityToHTML
function to transform links into real <a>
:
Editor:
Result after convertToHTML
:
Only because it's in a entity
(a link).
Why?
Do I have to use a decoder on originalText
to display the original text?
Hey,
Nice job with this plugin, just trying it at the moment and seems to work nicely except for one small issue...
I've using the draft-js-plugins-emoji plugin and so have code to replace the emoji entities:
if (entity.type === 'emoji') {
const unicode = escapeMap[entity.data.emojiUnicode];
return `<img class="emoji" alt="${entity.data.emojiUnicode}" src="${EMOJI_BASE_URL}${unicode}.png" />`;
}
The raw state I'm putting in (I convert it from the JS object using convertFromRaw first) is:
{
"entityMap":{
"0":{
"type":"emoji",
"mutability":"IMMUTABLE",
"data":{
"emojiUnicode":"π"
}
}
},
"blocks":[
{
"key":"69o72",
"text":"π ",
"type":"unstyled",
"depth":0,
"inlineStyleRanges":[
],
"entityRanges":[
{
"offset":0,
"length":1,
"key":0
}
],
"data":{
}
}
]
}
The output I get is the expected img tag followed by a οΏ½ character. Google informs me it is the "OBJECT REPLACEMENT CHARACTER".
I was just wondering if this is me misusing draft-convert or if something odd is going on during the conversion process?
Hi all, I dont know much abourt webpack and babel, but I'm using it for a while and this is the first time i encounter a problem.
Packaging draft-convert 1.4.3 works fine, but since 1.4.4-1.4.6 I get the following webpack error. Do I need to configure a babel loader to get it working? Any hint how to get it working is much appreciated!
ERROR in ./~/draft-convert/package.json
Module parse failed: <somePath>/frontendClient/resources/node_modules/draft-convert/package.json Unexpected token (2:9)
You may need an appropriate loader to handle this file type.
SyntaxError: Unexpected token (2:9)
at Parser.pp$4.raise (<somePath>/frontendClient/resources/node_modules/acorn/dist/acorn.js:2221:15)
at Parser.pp.unexpected (<somePath>/frontendClient/resources/node_modules/acorn/dist/acorn.js:603:10)
at Parser.pp.semicolon (<somePath>/frontendClient/resources/node_modules/acorn/dist/acorn.js:581:61)
at Parser.pp$1.parseExpressionStatement (<somePath>/frontendClient/resources/node_modules/acorn/dist/acorn.js:966:10)
at Parser.pp$1.parseStatement (<somePath>/frontendClient/resources/node_modules/acorn/dist/acorn.js:730:24)
at Parser.pp$1.parseBlock (<somePath>/frontendClient/resources/node_modules/acorn/dist/acorn.js:981:25)
at Parser.pp$1.parseStatement (<somePath>/frontendClient/resources/node_modules/acorn/dist/acorn.js:709:33)
at Parser.pp$1.parseTopLevel (<somePath>/frontendClient/resources/node_modules/acorn/dist/acorn.js:638:25)
at Parser.parse (<somePath>/frontendClient/resources/node_modules/acorn/dist/acorn.js:516:17)
at Object.parse (<somePath>/frontendClient/resources/node_modules/acorn/dist/acorn.js:3098:39)
at Parser.parse (<somePath>/frontendClient/resources/node_modules/webpack/lib/Parser.js:902:15)
at DependenciesBlock.<anonymous> (<somePath>/frontendClient/resources/node_modules/webpack/lib/NormalModule.js:104:16)
at DependenciesBlock.onModuleBuild (<somePath>/frontendClient/resources/node_modules/webpack-core/lib/NormalModuleMixin.js:310:10)
at nextLoader (<somePath>/frontendClient/resources/node_modules/webpack-core/lib/NormalModuleMixin.js:275:25)
at <somePath>/frontendClient/resources/node_modules/webpack-core/lib/NormalModuleMixin.js:259:5
at Storage.provide (<somePath>/frontendClient/resources/node_modules/enhanced-resolve/lib/CachedInputFileSystem.js:52:20)
at CachedInputFileSystem.readFile (<somePath>/frontendClient/resources/node_modules/enhanced-resolve/lib/CachedInputFileSystem.js:140:24)
at DependenciesBlock.onLoadPitchDone (<somePath>/frontendClient/resources/node_modules/webpack-core/lib/NormalModuleMixin.js:255:7)
at DependenciesBlock.loadPitch (<somePath>/frontendClient/resources/node_modules/webpack-core/lib/NormalModuleMixin.js:182:27)
at DependenciesBlock.doBuild (<somePath>/frontendClient/resources/node_modules/webpack-core/lib/NormalModuleMixin.js:241:4)
at DependenciesBlock.build (<somePath>/frontendClient/resources/node_modules/webpack/lib/NormalModule.js:84:14)
at Compilation.buildModule (<somePath>/frontendClient/resources/node_modules/webpack/lib/Compilation.js:126:9)
at <somePath>/frontendClient/resources/node_modules/webpack/lib/Compilation.js:309:10
at <somePath>/frontendClient/resources/node_modules/webpack/lib/NormalModuleFactory.js:58:13
at NormalModuleFactory.applyPluginsAsyncWaterfall (<somePath>/frontendClient/resources/node_modules/tapable/lib/Tapable.js:75:69)
at onDoneResolving (<somePath>/frontendClient/resources/node_modules/webpack/lib/NormalModuleFactory.js:38:11)
at onDoneResolving (<somePath>/frontendClient/resources/node_modules/webpack/lib/NormalModuleFactory.js:121:6)
at <somePath>/frontendClient/resources/node_modules/webpack/lib/NormalModuleFactory.js:116:7
at <somePath>/frontendClient/resources/node_modules/webpack/node_modules/async/lib/async.js:726:13
at <somePath>/frontendClient/resources/node_modules/webpack/node_modules/async/lib/async.js:52:16
@ ./~/draft-convert/lib/index.js 20:15-41
Hi,
Not sure if this is in-scope with draft-convert, but I'm trying to get a code block into my editor that renders as pure HTML. The editor is a pure internal tool (so we're not worried about malicious actors).
Things I've tried
{blockToHTML: (block) => {
if (block.type === 'code-block') {
return <div dangerouslySetInnerHTML={{ __html: block.text }}></div>
}
}
Can't set children and innerHTML
{blockToHTML: (block) => {
if (block.type === 'code-block') {
return {
start: block.text,
end: ''
}
}
}
Outputs: Correct output + text is repeated
It would be nice if there's a non-default way to avoid encoding the blocks so we can pass unsafe HTML in convertToHTML.
When attempting to generate a content state that has a link entity, convertFromHTML seems to work up until I try to serialize the contentState to JSON using DraftJS.convertToRaw.
The code I have is:
const newContentState = convertFromHTML({
htmlToEntity: (nodeName, node, createEntity) => {
if (nodeName === 'a') {
return createEntity(
'LINK',
'MUTABLE',
{ url: node.href },
);
}
},
This works great as long as I don't try to serialize it.
The error I get on serialization is:
convertFromDraftStateToRaw.js?f453:52 Uncaught TypeError: contentState.getEntity is not a function
at eval (convertFromDraftStateToRaw.js?f453:52)
at Array.forEach (<anonymous>)
at Object.convertFromDraftStateToRaw [as convertToRaw] (convertFromDraftStateToRaw.js?f453:51)
at htmlToBlock (EditDocument.jsx?1364:365)
at genFragment (convertFromHTML.js?2ed9:372)
at genFragment (convertFromHTML.js?2ed9:427)
at genFragment (convertFromHTML.js?2ed9:427)
at genFragment (convertFromHTML.js?2ed9:427)
at genFragment (convertFromHTML.js?2ed9:427)
at getChunkForHTML (convertFromHTML.js?2ed9:481)
I'm using Draft JS 0.10.1 from Megadraft, so I think there might be some sort of version incompatiblity between Draft 0.10.1 and the contentState generated by convertFromHTML. But draft-convert uses draft-js as a peer dependency so I'm a little unsure on how this could happen.
Hi! In convertFromHTML for links i can do this:
htmlToEntity: (nodeName, node) => {
if (nodeName === 'a') {
return Entity.create(
'LINK',
'MUTABLE',
{url: node.href}
)
}
}
htmlToEntity: (nodeName, node) => {
if (nodeName === 'img') {
return Entity.create(
'IMAGE',
'MUTABLE',
{src: node.src}
)
}
}
But it doesn't work. In draft-js editor img not showed.
I'm really sorry about this. I'm at a total loss here. The closest I've come to finding a resolution to this is here.
I am trying to convert
<div class="signature">
<p>Emperor Palpatine</p>
<p>Lord of the Sith</p>
<p>Totally framed the Jedi</p>
</div>
into a single content block, but when I try to convert it I end up with what is essentially
<div class="signature">Emperor Palpatine</div>
<p>Lord of the Sith</p>
<p>Totally framed the Jedi</p>
I feel like I'm missing something incredibly simple here. I recreated it outside of my application here
in this webpackbin
When having a <ol>
and in that a <li>
that has newlines in form of a <br>
in it, convertFromHTML will make every line in that <li>
it's own list item, that appears in the surrounding list, which is not the expected result.
Example:
<ol>
<li>first</li>
<li> second<br>
with<br>
newlines</li>
</ol>
will be converted to a list with the structure:
1. first
2. second
3. with
4. newlines
Every line of the second item is a ContentBlock with type 'ordered-list-item'
I just noticed the release of #43 which is super cool. Unfortunately, it does not work for intersections situations, which is problematic.
Here is my code:
convertToHTML({
blockToHTML: { // I put this here to have <div> in my output instead of <p>
unstyled: {
start: '<div>',
end: '</div>',
empty: '<br>',
}
},
entityToHTML: (entity, originalText) => {
if (entity.type === 'link') {
return {
start: `<a href="${entity.data.url}" target="_blank">`,
end: '</a>',
}
}
return originalText
}
})(contentState)
<div>t<strong>e<</strong>a href="http://google.com" target="_blank">st test</a></div>
Intersect start
Result:
Code:
<div>t<strong>e<</strong>a href="http://google.com" target="_blank">st test te</a>st</div>
Intersect end
Result:
Code:
<div>te<a href="http://google.com" target="_blank">st test t<strong>e<</strong>/a>st</div>
Currently empty text nodes are trimmed to one whitespace char. I assume it makes sense in some cases but if an entity is padded with some whitespaces, they are removed, and the appearance of the text is not as expected.
Example : convertFromHtml("<p>&nbps;&nbps;&nbps;&nbps;<a href='/home'>Link</a>&nbps;&nbps;&nbps;&nbps;</p>
") results in<p> <a href='/home'>Link</a> </p>
The 'link' word that was supposed to be padded with spaces is now aligned to the left with a single spaces.
This is the relevant code :
if (text.trim() === '' && inBlock !== 'code-block') {
return getWhitespaceChunk(inEntity);
}
It would be useful to have control over this functionality.
Hello,
do you have any typescript support for this plugin?
PS. this plugin saved my life! Thanks! ;)
Currently I'm converting to HTML like this which works fine:
const entityToHTML = (entity, originalText) => {
if (entity.type === BLOCK.SEPARATOR) return '<hr>';
}
And I convert from HTML the hr
like this:
htmlToEntity: (nodeName, node) => {
if (nodeName === 'hr') {
return Entity.create(BLOCK.SEPARATOR, IMMUTABLE, {});
}
}
htmlToBlock: (nodeName, node, lastList, inBlock) => {
if (nodeName === 'hr' && inBlock !== BLOCK.ATOMIC) {
return BLOCK.ATOMIC;
}
}
Then when I convert to HTML again, I end up with a hr wrapped in an atomic block.
I think this is because the text inside the atomic needs to be a '-' to be ahr
but turns into 'a' when we convert from HTML. Is there a way to set the text of an atomic on when converting from HTML?
I would like to solve the following issue:
Using convertFromHTML I can convert an image tag to an atomic content block, however I am trying to introduce an unstyled block before and after the image.
htmlToBlock only allows for returning a 1 - to - 1 translation. Is there any way to achieve this 1 - to - many translation, i.e. one HTML node translates into multiple content blocks.
Thanks
Hi all, thanks for this great library!
I'm playing with generating nested list by convertToHTML.
Say I have
The genereated nested uls are as in the test
<ul><li>1</li><ul><li>2</li></ul></ul>
Shouldn't it be
<ul><li>1<ul><li>2</li></ul></li></ul>
Meaning the ul is inside li?
Some discussion about it here
Is it because of the way draft js organizes its blocks?
Many thanks
I have made an email signature editor in DraftJS.
Users can pull in their current signature from Gmail, which comes in HTML.
When they open the editor we convert the HTML to DraftJS state using draft-convert but the formatting can often be quite off.
Sometimes it will have new lines where none were before or text will all be on the same line.
Here is a simplistic example where we have how text looks in HTML and when converted to DraftJS.
https://codepen.io/JohnMaguir/pen/OQbgLZ
An idea might be to try and manipulate the HTML before it goes to draft-convert but it would be hard to manipulate it and catch all scenarios without losing any of the users formatting.
I've also tried using custom htmlToBlock
method, where I return false to ignore any node that is just an empty div or a div that only includes a br tag, based on this - #62
This will stop the insertion of some blank lines but doesn't fix the issue of the first two lines being pushed together and I'm not sure if it will work for more complex HTML.
If this is a bug that needs to be fixed I can propose a pull request, just point me in the right direction, otherwise any and all ideas would be much appreciated. If you need any more info please let me know
A declarative, efficient, and flexible JavaScript library for building user interfaces.
π Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. πππ
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google β€οΈ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.