I have two realization with different approach but with almost the same code inside. but checkAnswer is working, checkAnswer2 is not
they are iterating through children of node and changes attributes of nodes particular type
checkAnswer2() {
const from = this.getPos();
const to = from + this.node.nodeSize;
this.editor.state.doc.nodesBetween(from, to, (node) => {
if (node.type.name === this.extension.options.inputNodeName) {
let classes = '';
if (node.attrs.value) {
classes = node.attrs.answers.includes(node.attrs.value) ? 'success' : 'error';
}
const position = node.attrs.position;
// const position = pos;
node.attrs.classes = classes;
const newAttrs = { ...node.attrs, classes: classes };
this.editor.view.state.tr.setNodeMarkup(position, undefined, newAttrs);
}
});
},
checkAnswer(node) {
if (!node?.content?.content?.length) {
if (node.type.name === this.extension.options.inputNodeName) {
this.checkFillGapsInput(node);
}
}
// проверяем потомков рекурсивно
if (node?.content?.content?.length) {
node.content.content.forEach((node) => this.checkAnswer(node));
}
},
checkFillGapsInput(node) {
let classes = '';
if (node.attrs.value) {
classes = node.attrs.answers.includes(node.attrs.value) ? 'success' : 'error';
}
const position = node.attrs.position;
node.attrs.classes = classes;
this.editor.view.state.tr.setNodeMarkup(position, undefined, node.attrs);
},
first one runs all the children recursively and checks if its the node type we need,
second uses nodesBetween where it takes getPos() as a begin and getPos() + nodeSize as the end
I noticed that in first function window.MutationObserver is triggered to rerender DOM, but in the second function editor state is kinda beeing updated but its not triggering browser DOM to update
here you can see that it does not checks the spelling at first time but when I trigger update data by new input it updates the class attribute and then get highlighted with green
second input the same, at first I filled the wrong answer, but right after the Check button it did not highlight red color, only after triggering state
may be, but how is it possible that the classes were applied
mutating the classes is the idea of the parent node, It has the “check answers” button, it iterates through child nodes of particular type and checks if the value of input is allowed
I understand that I shouldn’t mutate node.attrs properties directly. But changing them via transaction.setNodeAttribute or transaction.setNodeMarkup is okay, right? Just don’t forget to dispatch it.
If suggestion above is correct is it okay to update attributes of child nodes with setNodeAttribute method from parent node?