jpuri / html-to-draftjs

MIT License
158 stars 104 forks source link

image position is lost when converting from html to EditorState #101

Open Sergej-Vlasov opened 3 years ago

Sergej-Vlasov commented 3 years ago

when saving the image in react-draft-wysiwyg I get the following output as html:

<div style="text-align:right;"><img src="srcHere" alt="" style="height: auto;width: auto"/></div>

after converting this back to the EditorState and logging out html again I receive:

<p style="text-align:right;"></p> <img src="srcHere" alt="" style="height: auto;width: auto"/>

The image position is lost and wrapping div is converted into adjacent empty p element with same styling as div.

the code that converts the html back to EditorState:

  ...
  const contentBlock = htmlToDraft(fieldHtml);

  const contentState = ContentState.createFromBlockArray(contentBlock.contentBlocks);

  return EditorState.createWithContent(contentState);

I imagine this might be similar if not the same issue as #98

xutongbao commented 3 years ago

I have the same problem.Have you fixed this bug now? @Sergej-Vlasov @jpuri

xutongbao commented 3 years ago
//富文本html格式转换
const htmlFormat = (data) => {
  const json = html2json(data)
  Array.isArray(json.child) &&
    json.child.forEach((item) => {
      if (item.tag === 'div') {
        item.tag = 'img'
        if (
          item.attr &&
          Array.isArray(item.child) &&
          item.child.length === 1 &&
          item.child[0].attr &&
          Array.isArray(item.child[0].attr.style)
        ) {
          const style = item.attr.style + item.child[0].attr.style.join('')
          item.attr = {
            ...item.child[0].attr,
          }
          item.attr.style = style
        }
      }
    })

  const html = json2html(json)
  return html
}

  //解决image位置无法保存的bug
  const html = value.text ? htmlFormat(value.text) : ''
  const contentBlock = htmlToDraft(
    html,
    (nodeName, node) => {
      if (nodeName === 'img' && node instanceof HTMLImageElement) {
        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
        if (node.style.float) {
          entityConfig.alignment = node.style.float
        } else {
          if (node.style.textAlign) {
            entityConfig.alignment = node.style.textAlign
          }
        }

        return {
          type: 'IMAGE',
          mutability: 'MUTABLE',
          data: entityConfig,
        }
      }
    }
  )
ysfSt commented 1 year ago

I was facing the same issue, and since each image has a div parent with align-text property, the idea behind my solution is to find any matches (e.g. find any image with a div parent ), take the property from the div element and set it to the image


const blocksFromHTML = htmlToDraft(
          html,
          (nodeName, node) => {
            if (nodeName === 'img' && node instanceof HTMLImageElement) {
              if (node.parentElement instanceof HTMLDivElement) {    // for image with div element as a parent
                const entityConfig = {};
                const parentElement = node.parentElement;
                if (parentElement.style.float) {      // check float style property
                  entityConfig.alignment = parentElement.style.float;
                } else if (parentElement.style.textAlign) {   // check float style property
                  entityConfig.alignment = parentElement.style.textAlign;
                }

                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 {
                  type: 'IMAGE',
                  mutability: 'MUTABLE',
                  data: entityConfig,
                };
              }
            }
          }
        );
youba commented 1 year ago

Hello Guys !

It is wired, but I think that I've got a workaround (it is related to textAlign:none instead of center bug #989

const blocksFromHTML = htmlToDraft(
          html,
          (nodeName, node) => {
            if (nodeName === 'img' && node instanceof HTMLImageElement) {
              if (node.parentElement instanceof HTMLDivElement) {    // for image with div element as a parent
                const entityConfig = {};
                const parentElement = node.parentElement;
                if (parentElement.style.float) {      // check float style property
                  entityConfig.alignment = parentElement.style.float;
                } else if (parentElement.style.textAlign) {   // check float style property
                  entityConfig.alignment = parentElement.style.textAlign;
                        if (entityConfig.alignment === "center") {
                            entityConfig.alignment = "none";
                        }
                }
                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 {
                  type: 'IMAGE',
                  mutability: 'MUTABLE',
                  data: entityConfig,
                };
              }
            }
          }
        );