I am unable to get the simple behavior where the cursor can seamlessly enter and exit a node view, I expected this to be the default behavior when contentDOM
is defined in a node view, however by default it is seen as an atom, unless you explicitly click on some of the text within the node view.
I tried to get this behavior by checking from which side the cursor entered and then setting the selection to either the first (left) or last (right) character within the node view, but I cannot seem to get selection to work within a node view.
If I throw an exception within selectNode
, it does work the way I want, namely DOM marked not contentEditable
are considered atoms, the rest can have editable text. That probably is the default behavior of contentEditable
. This is the node view I am testing:
class TagView {
private dom: HTMLElement;
private contentDOM: HTMLElement;
constructor(
private node: ProseNode,
private view: EditorView,
private getPos: () => number,
private decorations: Decoration[]) {
console.log("TagView")
const tag = document.createElement("span");
tag.classList.add("tag");
const before = document.createElement("span");
before.classList.add("before");
before.appendChild(document.createTextNode("{{"));
before.contentEditable = "false";
const after = document.createElement("span");
after.classList.add("after");
after.appendChild(document.createTextNode("}}"));
after.contentEditable = "false";
const contents = document.createElement("span");
contents.classList.add("contents");
tag.appendChild(before);
tag.appendChild(contents);
tag.appendChild(after);
this.dom = tag;
this.contentDOM = contents;
}
setSelection() {
console.log("set selection");
}
selectNode() {
console.log("select node");
this.view.dispatch(this.view.state.tr.setSelection(TextSelection.create(this.view.state.doc, this.getPos())));
}
deselectNode() {
console.log("deselect node");
}
}
I thought maybe I misunderstood how selections worked, but when I tried them outside the node view, all my tests matched my expectations:
window.addEventListener("keydown", e => {
if (e.ctrlKey && e.keyCode === "D".charCodeAt(0)) {
e.preventDefault();
e.stopImmediatePropagation();
console.log("pressed ctrl+d");
const view = editorView;
const state = view.state;
const selection = TextSelection.create(state.doc, 3, 4)
// const selection = Selection.near(state.doc.resolve(4))
const selectTr = state.tr.setSelection(selection)
view.focus()
view.dispatch(selectTr)
// view.updateState(state.apply(selectTr))
}
});
Am I misunderstanding something about node views? I know I could workaround the issue by replicating what is done in the footnote example, but this would cost more resources and should not be necessary for simple cases.