如何解决Draft-JS - 使用 convertFromHTML 将 <img> 翻译成原子块摆脱了 Entity
所以我一直在尝试使用方法 convertFromHTML
将图像转换为原子块,以便它可以与 draft-js-image-plugin
兼容,因为它需要类型为 atomic
给定一个带有一些文本和图像的简单 HTML 结构,convertFromHTML
生成此 contentState
:
{
"blocks": [
{
"key": "82k8","text": "‐‐‐‐‐‐‐ Original Message ‐‐‐‐‐‐‐","type": "unstyled","depth": 0,"inlinestyleRanges": [],"entityRanges": [],"data": {}
},{
"key": "9jbor","text": "On December 29,2020,5:20 PM EST txwbi.nrjrtn@gmail.com wrote:","entityRanges": [{ "offset": 34,"length": 23,"key": 0 }],{
"key": "anq8o","text": "?A bunch of text here to test out the body","inlinestyleRanges": [
{ "offset": 3,"length": 13,"style": "ITALIC" },{ "offset": 3,"style": "UNDERLINE" },{ "offset": 38,"length": 4,"style": "BOLD" }
],"entityRanges": [{ "offset": 0,"length": 1,"key": 1 }],"data": {}
}
],"entityMap": {
"0": {
"type": "LINK","mutability": "MUTABLE","data": {
"href": "mailto:txwbi.nrjrtn@gmail.com","rel": "noreferrer nofollow noopener","target": "_blank","url": "mailto:txwbi.nrjrtn@gmail.com"
}
},"1": {
"type": "IMAGE","mutability": "IMMUTABLE","data": {
"alt": "cory_emoji.png","height": "210","src": "data:image/png;base64,...BASE64ENCODEDIMAGE WOULD BE HERE I REMOVED BECAUSE OF CHAR LIMITS","width": "173"
}
}
}
}
我们可以看到 img
标签采用了 unstyled
块,这不是我想要的。所以我创建了以下函数来扩展默认的块渲染映射以解释 img
标签:
const {
EditorState,convertToRaw,DefaultDraftBlockRenderMap,ContentState,convertFromHTML,getSafeBodyFromHTML
} = require('draft-js');
const Immutable = require('immutable');
module.exports.editorStateFromHTML = htmlBody => {
console.log('HTML ---> EDITOR ::: RAW BODY',htmlBody);
const blockRenderMap = Immutable.Map({
atomic: {
element: 'figure',aliasedElements: ['img']
}
});
const extendedBlockRenderMap = DefaultDraftBlockRenderMap.merge(
blockRenderMap
);
const blocksFromHTML = convertFromHTML(
htmlBody,getSafeBodyFromHTML,extendedBlockRenderMap
);
console.log(blocksFromHTML);
const state = ContentState.createFromBlockArray(
blocksFromHTML.contentBlocks,blocksFromHTML.entityMap
);
console.log(JSON.stringify(convertToRaw(state)));
const newEditor = EditorState.createWithContent(state);
return newEditor;
};
导致此内容状态:
{
"blocks": [
{
"key": "fhgqd",{
"key": "2nsnk",{
"key": "7c7cu","text": "A bunch of text here to test out the body","inlinestyleRanges": [
{ "offset": 2,{ "offset": 2,{ "offset": 37,{
"key": "f84vb","text": "","type": "atomic","url": "mailto:txwbi.nrjrtn@gmail.com"
}
}
}
}
如您所见,entityMap 现在只有一个键,图像的所有数据都不再存在。我怎样才能让 img
标签成为原子块,同时仍然在 entityMap 中创建 IMAGE
实体???
解决方法
我的解决方法是遵循它有点丑但它有效并为我提供了正确的输出:
const {
EditorState,convertToRaw,convertFromRaw,DefaultDraftBlockRenderMap,ContentState,convertFromHTML,getSafeBodyFromHTML
} = require('draft-js');
const Immutable = require('immutable');
const clone = require('rfdc')();
module.exports.editorStateFromHTML = htmlBody => {
console.log('HTML ---> EDITOR ::: RAW BODY',htmlBody);
const blockRenderMap = Immutable.Map({
image: {
element: 'img'
}
});
const extendedBlockRenderMap = DefaultDraftBlockRenderMap.merge(
blockRenderMap
);
const blocksFromHTML = convertFromHTML(
htmlBody,getSafeBodyFromHTML,extendedBlockRenderMap
);
const state = ContentState.createFromBlockArray(
blocksFromHTML.contentBlocks,blocksFromHTML.entityMap
);
const { blocks,entityMap } = convertToRaw(state);
const imgCount = blocks.filter(b => b.type === 'image').length;
if (imgCount > 0) {
const fixedEntityMap = clone(entityMap);
let arrKeys = Object.keys(fixedEntityMap);
arrKeys = arrKeys.map(k => parseInt(k,10));
const lastKey = Math.max(...arrKeys);
let blockCounter = lastKey;
const fixedContentBlocks = blocks.map(blck => {
if (blck.type === 'image') {
blockCounter += 1;
return {
...blck,text: ' ',type: 'atomic',entityRanges: [{ offset: 0,length: 1,key: blockCounter }]
};
}
return blck;
});
const blocksFromHTML2 = convertFromHTML(htmlBody);
const state2 = ContentState.createFromBlockArray(
blocksFromHTML2.contentBlocks,blocksFromHTML2.entityMap
);
const { entityMap: imgEntities } = convertToRaw(state2);
let entityCounter = lastKey;
// eslint-disable-next-line no-restricted-syntax
for (const [key,value] of Object.entries(imgEntities)) {
if (value.type === 'IMAGE') {
entityCounter += 1;
fixedEntityMap[entityCounter] = value;
}
}
const editorDefaultValue = {
blocks: fixedContentBlocks,entityMap: fixedEntityMap
};
return EditorState.createWithContent(convertFromRaw(editorDefaultValue));
}
return EditorState.createWithContent(state);
};
如果有人有更好的解决方案,我会全力以赴。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。