简体   繁体   中英

simply replace a node's content in prosemirror

I'm in a function that receives a string as input:

(text) => {

}

I have access to the editor via Vue props ( props.editor ). I would like to replace the current node's content with this text. I cannot seem to find out how to do this. I'm using tiptap2, which is a wrapper around ProseMirror and has access to all of ProseMirror's api.

I'd rather not try to replace the whole node unless necessary, which I also tried, doing below – but cannot get that to work either:

(text) => {
        props.editor
          .chain()
          .focus()
          .command(({ tr }) => {
            const node = props.editor.state.schema.nodes.paragraph.create(
              { content: text}
            );
            tr.replaceSelectionWith(node);

            return true;
          })
          .run();
}

Much thanks

I'm late to the party but this is the top result I came across when trying to find a solution for myself.

My code is in the context of a React NodeView, so I'm given a getPos() prop that gives the position of the React node in the Prosemirror document (I believe this number more-or-less means how many characters precede the React NodeView node). With that I was able to use this command chain to replace the content:

import { Node as ProsemirrorNode } from "prosemirror-model";
import { JSONContent, NodeViewProps } from "@tiptap/react";

const NodeViewComponent = (props: NodeViewProps) => 
  // ...

  /**
   * Replace the current node with one containing newContent.
   */
  const setContent = (newContent: JSONContent[]) => {
    const thisPos = props.getPos();

    props.editor
      .chain()
      .setNodeSelection(thisPos)
      .command(({ tr }) => {
        const newNode = ProsemirrorNode.fromJSON(props.editor.schema, {
          type: props.node.type.name,
          attrs: { ...props.attrs },
          content: newContent,
        });

        tr.replaceSelectionWith(newNode);

        return true;
      })
      .run();
  };

  // ...
};

Basically you want to:

  1. Set the current selection to the node you want to replace the content of
  2. Create and update a new node that is a copy of the current node
  3. Replace your selection with the new node.

This solution works for me in Tiptap version 2. A precondition for this to work is, that the text to be replaced is marked (highlighted).

const selection = editor.view.state.selection;
editor.chain().focus().insertContentAt({
    from: selection.from,
    to: selection.to
}, "replacement text").run();

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM