Hi My nodespec is as below , it renders correctly when i dont use custom nodeview. I can type something in the blank node because contenteditable is not written as false. The code jumps in to DOMSerializer.renderSpec
method.
group: 'inline',
content: 'text*',
inline: true,
attrs: {
id: { default: '' },
class: { default: 'fill-the-blank' },
answer: { default: '' },
},
toDOM(node) {
return [
'span',
{
class: node.attrs.class,
id: node.attrs.id,
'data-answer': node.attrs.answer,
},
['span', {}, 0] // Inner span for content
];
},
The core code of prosemirror renders it differently …
// Node view descs are the main, most common type of view desc, and
// correspond to an actual node in the document. Unlike mark descs,
// they populate their child array themselves.
class NodeViewDesc extends ViewDesc {
constructor(parent, node, outerDeco, innerDeco, dom, contentDOM, nodeDOM, view, pos) {
super(parent, [], dom, contentDOM);
this.node = node;
this.outerDeco = outerDeco;
this.innerDeco = innerDeco;
this.nodeDOM = nodeDOM;
}
// By default, a node is rendered using the `toDOM` method from the
// node type spec. But client code can use the `nodeViews` spec to
// supply a custom node view, which can influence various aspects of
// the way the node works.
//
// (Using subclassing for this was intentionally decided against,
// since it'd require exposing a whole slew of finicky
// implementation details to the user code that they probably will
// never need.)
static create(parent, node, outerDeco, innerDeco, view, pos) {
let custom = view.nodeViews[node.type.name], descObj;
let spec = custom && custom(node, view, () => {
// (This is a function that allows the custom view to find its
// own position)
if (!descObj)
return pos;
if (descObj.parent)
return descObj.parent.posBeforeChild(descObj);
}, outerDeco, innerDeco);
let dom = spec && spec.dom, contentDOM = spec && spec.contentDOM;
if (node.isText) {
if (!dom)
dom = document.createTextNode(node.text);
else if (dom.nodeType != 3)
throw new RangeError("Text must be rendered as a DOM text node");
}
else if (!dom) {
({ dom, contentDOM } = DOMSerializer.renderSpec(document, node.type.spec.toDOM(node)));
}
if (!contentDOM && !node.isText && dom.nodeName != "BR") { // Chrome gets confused by <br contenteditable=false>
if (!dom.hasAttribute("contenteditable"))
dom.contentEditable = "false";
if (node.type.spec.draggable)
dom.draggable = true;
}
let nodeDOM = dom;
dom = applyOuterDeco(dom, outerDeco, node);
if (spec)
return descObj = new CustomNodeViewDesc(parent, node, outerDeco, innerDeco, dom, contentDOM || null, nodeDOM, spec, view, pos + 1);
else if (node.isText)
return new TextViewDesc(parent, node, outerDeco, innerDeco, dom, nodeDOM, view);
else
return new NodeViewDesc(parent, node, outerDeco, innerDeco, dom, contentDOM || null, nodeDOM, view, pos + 1);
}
But when i use a custom nodeview for better control in the rendering , prosmirror adds contenteditable as false and hence i cannot type inside the blank .
Not sure if i have to forcefully add contenteditable as true , or i am missing something.