Upon initial creation, there is no <br> inside the node. But when I try to delete it via ‘tr.delete(startPos, endPos)’, the node itself does not get deleted, only the content is replaced with a single <br>. What I need is to actually delete the node so it does not take space inside my document.
The positions of the nodes are as follows
278| foo |287
279| bar |286
279| text |285
No matter what positions I pass to ‘tr.delete()’ (tried some cases with -2, -1, +1, +2), it either places the content that follows ‘foo’ inside it or leaves <foo><bar><br></bar></foo> Any idea what could I do to get the node deleted? Please note that I do not have ‘inline: true’ on any of the two nodes
Does your schema allow the foo node to be deleted, or is something required in the place that it takes up in its parent node? I can’t quite follow your diagrams, but deleting from the position before a node to the one after it (maybe use doc.resolve(pos).toString() to debug your positions) should delete it, if it’s allowed to be deleted. Transaction methods act on the document level, so node views and DOM-related issues should not be relevant.
The diagram was regarding the positions of the nodes displayed in the dev tools
My page schema is with content ‘(ElemA | foo | ElemB)*’ so that wasn’t the issue.
Once I changed the content of ‘foo’ to be ‘bar*’ instead of just ‘bar’, I was able to delete the node. Does that mean that I need to make every single node in a hierarchy optional, in order to be able to delete a parent node?
It was too early to open the champagne. My change only removed the inner “bar” node, but the “foo” wrapper was still in the DOM and PM State. Looks like the issue has something to do with my custom view, because after removing it from nodeViews: config of the EditorView, I am able to delete the nodes using the same code as before tr.delete(pos, node.nodeSize)
My custom views:
class BaseView {
constructor(node, view, getPos) {
// getting attributes to set to the dom element
// let attrs = ...
this.dom = this.contentDOM = document.createElement(this.nodeType);
for (const attr in attrs) {
this.dom.setAttribute(attr, attrs[attr]);
}
//.. some logic related to opening popup upon click
}
destroy() {
// detaching event handlers, no need?
}
stopEvent() { return true; }
}
class FooView extends BaseView {
constructor(node, view, getPos) {
super(node, view, getPos);
this.template = view.state.doc.attrs.template;
}
update(node, decos) {
this.dom.firstChild.innerHTML = `${this.template.fooTemplate} ${node.attrs.numbering}`;
return true;
}
get nodeType() {
return 'foo';
}
}
these lines were causing the issue. After removing them, the nodes are being deleted. Any ideas why? Using textContent instead of innerHTML does not work as well.
The update method should at least check whether the given node is of the expected type, and return false otherwise. In this case, it’s claiming to have updated to whatever happened to come after it in the document.
(You’re not the first to trip over this and the use case of node views being able to update to other node types is rare, but that’s currently something we support.)
Upon opening the popup I get the attribute value from node.attrs.duration. Because of the update method, that attribute is always “null” (default value). But it starts working again when update method of the view is removed/commented. Any idea what else am I doing wrong (or not doing :?) inside that update method?
Edit: For now I have made a workaround, updating the text of the node with tr.insertText because of close deadlines, but I will eventually come back to the issue later and post any new findings.