SVG defs Disappears During compositionstart in ProseMirror When Typing in Chinese

I am working on a rich text editor using ProseMirror and have implemented a custom nodeView for rendering text with SVG gradient effects. However, I’ve encountered an issue where the SVG defs section disappears during the compositionstart event when typing in Chinese, and it only reappears after the compositionend event.

Here’s a detailed description of the problem:

  1. When I start typing using the Chinese input method (triggering the compositionstart event), the defs part of the SVG is not visible.
  2. Once I finish typing (triggering the compositionend event), the defs section reappears as expected.

I have tried the following to address this issue:

  • Ensuring that the SVG and defs elements are correctly created within the nodeView.
  • Utilizing requestAnimationFrame for optimizing DOM updates.

Despite these efforts, the problem remains unresolved. Below is a relevant snippet of my code:

export const initProsemirrorEditor = (dom: Element, content: string, props = {}) => {
  const editor = new EditorView(dom, {
    state: EditorState.create({
      doc: createDocument(content),
      plugins: buildPlugins(schema),
    }),
    ...props,
    nodeViews: {
      'svgGradientText': (node) => {
        let dom = document.createElement('span');
        dom.className = 'svg-gradient-text';
        dom.setAttribute('data-gradient-id', node.attrs.id);
        dom.style.display = 'inline-block';
        dom.style.maxWidth = '100%'
        const xmlNS = 'http://www.w3.org/2000/svg'
        let text = document.createElementNS(xmlNS, 'text') as any;
        text.setAttribute('x', '50%');
        text.setAttribute('y', '50%');
        text.setAttribute('style', 'text-anchor: middle; dominant-baseline: middle; fill: url(#' + node.attrs.id + '); text-shadow: 0 8px 0 #333; stroke-width: 6px; stroke: #333; paint-order: stroke; stroke-linejoin: round;font-size:40px');

        let svg = document.createElementNS(xmlNS, 'svg');

        let defs = document.createElementNS(xmlNS, 'defs');
        let linearGradient = document.createElementNS(xmlNS, 'linearGradient');
        linearGradient.setAttribute('id', node.attrs.id);
        linearGradient.setAttribute('x1', '0');
        linearGradient.setAttribute('y1', '0');
        linearGradient.setAttribute('x2', '0');
        linearGradient.setAttribute('y2', '1');

        let stop1 = document.createElementNS(xmlNS, 'stop');
        stop1.setAttribute('offset', '0%');
        stop1.setAttribute('stop-color', '#FFCF02');
        linearGradient.appendChild(stop1);

        let stop2 = document.createElementNS(xmlNS, 'stop');
        stop2.setAttribute('offset', '100%');
        stop2.setAttribute('stop-color', '#FF7352');
        linearGradient.appendChild(stop2);

        defs.appendChild(linearGradient);
        svg.appendChild(defs);


        svg.appendChild(text)
        dom.appendChild(svg)

        nextTick(() => {
          const bbox = text.getBBox();
          if (bbox.width === 0) return
          svg.setAttribute('width', bbox.width + 10);
          svg.setAttribute('height', bbox.height + 10);
        })

        return {
          dom,
          contentDOM: text,
        }
      }
    },
  })
  return editor
}
const svgGradientText: MarkSpec = {
  group: 'inline',
  attrs: {
    id: { default: 'gradient' },
  },
  toDOM: mark => ['span', { 'class': 'svg-gradient-text', 'data-gradient-id': mark.attrs.id }, 0],
  parseDOM: [{
    tag: 'span.svg-gradient-text',
    getAttrs: dom => {
      const id = dom.getAttribute('data-gradient-id');
      return { id };
    }
  }]
}

blob_chrome-extension___gfdjdffkieeodoojhhmbodbgmmfbnkjm_a99c130d-8def-4e1e-ab06-230a0b91eff8

I am hoping to find a solution through the community’s help to ensure that the defs part of the SVG is displayed correctly even during the composition input phase of the Chinese input method.

Has anyone encountered a similar issue? Or do you have any suggestions that could help me resolve this problem?

I would greatly appreciate your time and assistance!