How intercept composition text into other position(selection) maintaining composing?

Hello,

I want to use inline node as chip.

export const FlavorNode: NodeSpec = {
  group: "inline",
  content: "text*",
  inline: true,
  selectable: true,
  draggable: true,

  attrs: {
    code: {},
    name: {},
  }, 

  toDOM: (node) => {
    return [
      "span",
      {
        "data-flavor-code": node.attrs.code,
        "data-flavor-name": node.attrs.name,
        class: "prosemirror-mention-node",
      },
      0,
    ]
  },

  parseDOM: [
    {
      tag: "span[data-flavor-code][data-flavor-name]",

      getAttrs: (dom) => {
        if (typeof dom === "string" || dom.nodeType !== Node.ELEMENT_NODE)
          return {};
        const element = dom as Element;
        var code = element.getAttribute("data-flavor-code");
        var name = element.getAttribute("data-flavor-name");
        return {
          code: code,
          name: name,
        };
      }
    }
  ],
};

I want to set selection inside and outside, so I reference prosemirror-codemark and make a plugin.

(example: ProseMirror Code Mark ) (document work have not done… due to incomplete implement. sorry) (you can make node wrap ‘/’ like /text/) SHANA2022-02-27 05-33-32 (2)

I have a problem handling composition input. At right outside and Left inside of span(usally not able to set cursor), I implement as prosemirror-nodemark/plugin.ts at b52ca660f26e4243bf1b77dc5566cb351c62bda7 · DearRAMA/prosemirror-nodemark · GitHub

But in android chrome. It break.

SHANAKakaoTalk_20220227_055011426

In prosemirror-codemark, using addStoredMark and removeStoredMark default feature, intercept composition input and insert other position.

(I modify no-cursor style.)

Pink cursor is actual cursor and black one is virtual cursor.

Originally, ‘테스트’ should be inserted inside of span(actual cursor position) but inserted outside of span maintaining composing.

SHANA2022-02-27 05-19-18 (2)

How can I use this feature or how do I implement?

Would your node work as a mark instead? Inline nodes with content are not very well supported by this library — you can create them, but editing on their edges is dodgy, because browsers don’t distinguish between cursors inside and outside the node, resulting in problems like this. Sometimes you can find CSS kludges that help, like setting the node to display: inline-block and/or rendering dummy text like zero-width spaces before and after the node so that the browser understands that there is a boundary there, but these depending on the situation these may not be easy to get to work.

Negative. one node has a meta about a flavor and should be maintain one span. As I know mark can be splitted like

<b>abc</b><span data-code="john"><b>def</b></span><span data-code="john">ghi</span>
content: [
  {
    'type': 'text',
    'content': 'abc',
    'mark': ['b'],
  },
  {
    'type': 'text',
    'content': 'def',
    'mark': ['b', 'span'],
  },
  {
    'type': 'text',
    'content': 'ghi',
    'mark': ['span'],
  },
]

Maybe inserting zero-width spaces before and after the node can be helpful for me. How can I implment for that. Using plugin and decoration? or define toDOM of NodeSpec? Can you tell me how to do? @marijn

thanks.

A node view is probably the best way to do that.

Can you tell me how to implement detail, @marijn ?

I try

export const FlavorNode2: NodeSpec = {
  group: "inline",
  inline: true,
  selectable: true,
  draggable: true,
  content: "text*",

  attrs: {
    code: {},
    name: {},
  },
 
  toDOM: (node) => {
    const dom = new DocumentFragment();
    const span = document.createElement('span');
    span.setAttribute('data-flavor-code', node.attrs.code);
    dom.append('\u200B', span, '\u200B')

    return {
      dom: dom,
      contentDOM: span,
    }
  },

  parseDOM: [
    {
      tag: "span[data-flavor-code]",

      getAttrs: (dom) => {
        if (typeof dom === "string" || dom.nodeType !== Node.ELEMENT_NODE)
          return {};
        const element = dom as Element;
        var code = element.getAttribute("data-flavor-code");
        return {
          code: code,
          name: name,
        };
      }
    }
  ],
};

but cursor work strange SHANA2022-03-01 23-35-58