convertFromHTML返回空响应| 草稿

cod*_*sed 0 reactjs draftjs

我确定我做错了。但是,一个简单的空html标记会导致convertFromHTML调用出现问题。

convertFromHTML("<p>  </p>"); // returns null
Run Code Online (Sandbox Code Playgroud)

如:

convertFromHTML("<p>empty</p>"); // returns a valid object.
Run Code Online (Sandbox Code Playgroud)

有思想的儿子为什么会这样?

vap*_*aid 6

convertFromHTML("<p> </p>"); // returns null

我假设“返回null”的字面意思是在这种情况下,更新到最新draft-js版本应该可以解决该问题。

这是我的示例运行

  • create-react-app v1.5.2
  • draft-js v0.10.5

console.log(convertFromHTML('<p> </p>'))

convertFromHTML的控制台日志

有一个“有效”对象,但contentBlocks属性为null,这意味着我们无法创建有效对象,ContentState因为您将获得以下信息:

TypeError: Cannot read property 'contentBlocks' of null
Run Code Online (Sandbox Code Playgroud)

有什么想法可能会发生吗?

简短答案: HTML节点需要文本。

深入解答:

编写本文时,以下所有代码均改编自最新版本的draft-js 源代码(提交4c4465f)。为了简洁起见,省略了一些方法部分。

该方法convertFromHTMLtoContentBlocks称为该模块,它具有几个主要步骤:

  1. 处理html字符串
  2. 从字符串创建一个DOM
  3. 从DOM产生块
  4. 将块映射到contentBlocks对象

1)将字符串处理为DOM html 是通过创建getChunkForHTML输出的方法来处理的contentBlocks

const convertFromHTMLtoContentBlocks = (
  html: string,
  DOMBuilder: Function = getSafeBodyFromHTML,
  blockRenderMap?: DraftBlockRenderMap = DefaultDraftBlockRenderMap,
): ?{contentBlocks: ?Array<BlockNodeRecord>, entityMap: EntityMap} => {

  const chunkData = getChunkForHTML( // processing our html string into chunkData
    html,
    DOMBuilder,
    blockRenderMap,
    DraftEntity,
  );

  // use the chunkData to create contentBlocks
  const {chunk, entityMap} = chunkData;
  const contentBlocks = convertChunkToContentBlocks(chunk);

  return {
    contentBlocks,
    entityMap,
  };
};
Run Code Online (Sandbox Code Playgroud)

检查时getChunkForHTML,我们看到空白被裁剪<p></p>并传递给DOMBuilder。由创建的DOM由DOMBuilder转换为genFragment,成块并作为返回chunk

const getChunkForHTML = (
  html: string,
  DOMBuilder: Function,
  blockRenderMap: DraftBlockRenderMap,
  entityMap: EntityMap,
): ?{chunk: Chunk, entityMap: EntityMap} => {
  html = html  // the string is trimmed
    .trim()
    .replace(REGEX_CR, '')
    .replace(REGEX_NBSP, SPACE)
    .replace(REGEX_CARRIAGE, '')
    .replace(REGEX_ZWS, '');

  const safeBody = DOMBuilder(html); // create DOM from trimmed html
  if (!safeBody) {
    return null;
  }

  const fragment = genFragment( 
    entityMap,
    safeBody,   // use DOM to create blocks in genFragment
    OrderedSet(),
    'ul',
    null,
    workingBlocks,
    -1,
    blockRenderMap,
  );


  let chunk = fragment.chunk;
  const newEntityMap = fragment.entityMap;

  // rest of method
  return {chunk, entityMap: newEntityMap};
};
Run Code Online (Sandbox Code Playgroud)

2)从字符串创建DOM 如果我们在调试器中检查DOMBuilder方法(的别名getSafeBodyFromHTML)(source),我们会看到获得具有以下属性的DOM节点:

innerHTML: "<p></p>"
innerText:""
Run Code Online (Sandbox Code Playgroud)

3)从DOM生成块 的输出DOMBuildergenFragmentas 的参数safeBody。此方法将DOM树处理为块。假设我们的DOM不包含文本,则从中返回的对象将genFragment具有属性:text: ""

genFragment块

4)将块映射到contentBlocks

中的最后一个通话convertFromHTMLtoContentBlocks

const contentBlocks = convertChunkToContentBlocks(chunk);

const convertChunkToContentBlocks = (chunk: Chunk): ?Array<BlockNodeRecord> => {
  if (!chunk || !chunk.text || !Array.isArray(chunk.blocks)) {
    return null;
  }
  // rest of method
}
Run Code Online (Sandbox Code Playgroud)

显然,此时chunk.text返回false,因此contentBlocksnull