diff --git a/src/lib/editor.component.scss b/src/lib/editor.component.scss index 48fd0590..7ba2e934 100644 --- a/src/lib/editor.component.scss +++ b/src/lib/editor.component.scss @@ -36,11 +36,14 @@ $menubar-text-padding: 0 $menu-item-spacing; } .NgxEditor__Placeholder { - color: #6c757d; - opacity: 1; - user-select: none; - position: absolute; - cursor: text; + &::before { + color: #6c757d; + opacity: 1; + user-select: none; + position: absolute; + cursor: text; + content: attr(data-placeholder); + } } .NgxEditor__Content { diff --git a/src/lib/plugins/placeholder.ts b/src/lib/plugins/placeholder.ts index 79c26f66..8d046983 100644 --- a/src/lib/plugins/placeholder.ts +++ b/src/lib/plugins/placeholder.ts @@ -1,5 +1,6 @@ import { Plugin, EditorState, PluginKey, Transaction } from 'prosemirror-state'; import { DecorationSet, Decoration } from 'prosemirror-view'; +import { Node as ProseMirrorNode } from 'prosemirror-model'; const PLACEHOLDER_CLASSNAME = 'NgxEditor__Placeholder'; @@ -17,7 +18,7 @@ const placeholderPlugin = (text?: string): Plugin => { }, props: { decorations(state: EditorState): DecorationSet { - const doc = state.doc; + const { doc } = state; const placeholder = this.getState(state); @@ -25,6 +26,9 @@ const placeholderPlugin = (text?: string): Plugin => { return DecorationSet.empty; } + const decorations: Decoration[] = []; + + const decorate = (node: ProseMirrorNode, pos: number) => { if (doc.childCount === 1 && doc?.firstChild?.isTextblock && doc.firstChild.content.size === 0) { const placeHolderEl = document.createElement('span'); placeHolderEl.classList.add(PLACEHOLDER_CLASSNAME); @@ -32,7 +36,17 @@ const placeholderPlugin = (text?: string): Plugin => { return DecorationSet.create(doc, [Decoration.widget(1, placeHolderEl)]); } - return DecorationSet.empty; + const placeholderNode = Decoration.node(pos, (pos + node.nodeSize), { + class: PLACEHOLDER_CLASSNAME, + 'data-placeholder': placeholder + }); + + decorations.push(placeholderNode); + } + }; + + doc.descendants(decorate); + return DecorationSet.create(doc, decorations); } } });