简体   繁体   中英

Apply decorations on edited text for Prosemirror object text

I have a Prosemirror Editor text and, I created a plugin that applies some decorations for text. It's been working pretty well, however, when I try to edit the text, it looks really buggy, and the styles are not properly applied to the text which is been edited.

The text originally had an orange background, but when I start to edit the text with decorations, the decoration from the moment that start to update onwards disappear or only shows in some parts

The video down below demonstrates the issue:

https://imgur.com/RCETIoO

Basically, this is the code that generates the Decorations:

export const getDecorationsForAnnotations = (
  doc: any,
  data: Data[],
  selectedDataId?: string
) => {
  let decos: any[] = [];
  let initialPos: number | undefined = undefined;
  let finalPos: number | undefined = undefined;
  doc.descendants((node: Node, pos: number, parent: any) => {
   ...
    // ... my logic to filter nodes here

          decos.push(
            Decoration.inline(pos, pos + parent.content.size, {
              style: S.DECORATED_PROSEMIRROR_ANNOTATED_SELECTED_NODE,
            })
          );
        }
      }
    }

    return true;
  });

  return { decos };
};

export const getHighlightAnnotationsPlugin = (
  ...
) => {
  return new Plugin({
    key: new PluginKey("pluginHighlightNotes"),
    state: {
      init(config, editorState) {
        const doc = editorState.doc as any;
        return DecorationSet.create(doc, []);
      },
      apply(transaction, oldEditorState, newEditorState) {
        let data: Data[] | undefined = undefined;
        let decorationSet = undefined;
        let selectedDataId = undefined;
        const mark = new Mark(); // being used to pass metadata to pluginView ( to add components in the DOM )

        if (transaction.getMeta("isTransactionToListen")) {
          data = transaction.getMeta("data") as Data[];
          selectedDataId = transaction.getMeta("selectedDataId") as string;
        } else {
          if (!data && oldEditorState instanceof DecorationSet) {
            // reuse previous state and decorations
            decorationSet = oldEditorState;
          }
        }

        if (!decorationSet && data?.length) {
          const doc = transaction.doc;
          const { decos } = getDecorationsForAnnotations(
            doc,
            data,
            selectedDataId
          );

          decorationSet = DecorationSet.create(doc, decos);
        }

        return decorationSet ? decorationSet : DecorationSet.create(transaction.doc, []);
      },
    },
    view: (editorView: any) => {
      return new pluginView(...);
    },
    props: {
      decorations(state) {
        return this.getState(state);
      },
    },
  });
};

I could solve this problem by doing this:

  1. In the pluginView:
      return new pluginView(...);
    },

extract the mouse cursor position (lastState.selection.ranges[0])

  1. Check if the cursor position is inside a decorated text range
  2. If the cursor is inside a decorated text range, then trigger a new Prosemirror transaction to refresh the decorations on the text

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