0

我已将我的 slate 版本升级到 0.66.5 并将 slate-react 升级到 0.68.0,但现在我遇到了以下问题:

在此处输入图像描述

当我从第三方来源粘贴 html 内容时,会出现此问题。

代码片段如下:

const withHtml = (editor) => {
  const { insertData, insertText, isInline } = editor;

  editor.isInline = (element) => {
    return element.type === "link" ? true : isInline(element);
  };

  editor.insertData = data => {
    const html = data.getData('text/html')

    if (html) {
      const parsed = new DOMParser().parseFromString(html, 'text/html')
      //console.log('parsed', parsed)
      const fragment = deserialize(parsed.body)

      console.log('fragment', fragment)

      Transforms.insertFragment(editor, fragment)
      return
    }

    insertData(data)
  }

  return editor;
};

export const deserialize = (el) => {

  if (el.nodeType === 3) {
    return el.textContent
  } else if (el.nodeType !== 1) {
    return null
  } else if (el.nodeName === 'BR') {
    return '\n'
  }

  const { nodeName } = el
  console.log('nodename', nodeName)
  let parent = el

  let children = Array.from(parent.childNodes)
    .map(deserialize)
    .flat()

  if (children.length === 0) {
    children = [{ text: '' }]
  }

  if (el.nodeName === 'BODY') {
    return jsx('fragment', {}, children)
  }


  if (ELEMENT_TAGS[nodeName]) {
    const attrs = ELEMENT_TAGS[nodeName](el)
    return jsx('element', attrs, children)
  }

  if (TEXT_TAGS[nodeName]) {
    const attrs = TEXT_TAGS[nodeName](el)
    return children.map(child => jsx('text', attrs, child))
  }

  console.log('children', children)

  return children
}


const ELEMENT_TAGS = {
  A: el => ({ type: 'link', url: el.getAttribute('href') }),
  BLOCKQUOTE: () => ({ type: 'quote' }),
  H1: () => ({ type: 'heading-one' }),
  H2: () => ({ type: 'heading-two' }),
  H3: () => ({ type: 'heading-three' }),
  H4: () => ({ type: 'heading-four' }),
  H5: () => ({ type: 'heading-five' }),
  H6: () => ({ type: 'heading-six' }),
  LI: () => ({ type: 'list-item' }),
  OL: () => ({ type: 'numbered-list' }),
  P: () => ({ type: 'paragraph' }),
  PRE: () => ({ type: 'code' }),
  UL: () => ({ type: 'bulleted-list' })
}

const TEXT_TAGS = {
  CODE: () => ({ code: true }),
  DEL: () => ({ strikethrough: true }),
  EM: () => ({ italic: true }),
  I: () => ({ italic: true }),
  S: () => ({ strikethrough: true }),
  STRONG: () => ({ bold: true }),
  U: () => ({ underline: true })
}

const EditAnswerView = ({ initialValue, onContentChange }) => {
  const editor = useMemo(
    () => withHtml(withReact(withHistory(createEditor()))),
    []
  );
  const [value, setValue] = useState(initialValue);
  const renderElement = useCallback((props) => <Element {...props} />, []);
  const renderLeaf = useCallback((props) => <Leaf {...props} />, []);

  const handleChange = (value) => {
    setValue(value);
    onContentChange(value);
  };

  return (
    <Slate editor={editor} value={value} onChange={handleChange}>
      <Card className="lt-editor">
        <div className="lt-editor__toolbar">
          <MarkButton format="bold" icon="bold" />
          <MarkButton format="italic" icon="italic" />
          <MarkButton format="underline" icon="underline" />
          <LinkButton />
          {/* <MarkButton format="link" icon="link" /> */}
          <Divider />
          <BlockButton format="heading-one" icon="header-one" />
          <BlockButton format="heading-two" icon="header-two" />
          <BlockButton format="block-quote" icon="citation" />
          <Divider />
          <BlockButton format="numbered-list" icon="numbered-list" />
          <BlockButton format="bulleted-list" icon="properties" />
        </div>
        <Editable
          className="lt-editor__body"
          renderElement={renderElement}
          renderLeaf={renderLeaf}
          placeholder="Enter some rich text…&quot;
          spellCheck
          autoFocus
          onKeyDown={(event) => {
            for (const hotkey in HOTKEYS) {
              if (isHotkey(hotkey, event)) {
                event.preventDefault();
                const mark = HOTKEYS[hotkey];
                toggleMark(editor, mark);
              }
            }
          }}
        />
      </Card>
    </Slate>
  );
};
4

0 回答 0