I am attempting to incorporate ProseMirror into a form field widget for the popular open-source ERP product Odoo. When updating the editor with a newly created state the function EditorView.prototype.updateState() is calling scrollRectIntoView() which walks up the DOM tree looking for the body tag. Odoo is doing a lot of DOM manipulation, so the div at which ProseMirror is anchored has no body node as a parent. The walk up the DOM ends in an exception when the parent is null.
Is there some way to suppress the scrolling or to provide it with a alternative rectangle to use instead of searching for the body? In any case, the true bounding box would be the immediate parent div, not the page body.
Could you describe the exception in a bit more detail – I’m seeing an if (!parent) break at the top of the loop in scrollRectIntoView, which seems like it should cover the case of the editor being in a detached DOM tree.
Thank you for looking at this. The full exception trace is as follows (Odoo bundles the javascript files)
at parentNode (http://localhost:8069/web/content/541-ad2a281/web.assets_backend.js:4782:67)
at scrollRectIntoView (http://localhost:8069/web/content/541-ad2a281/web.assets_backend.js:4784:33)
at EditorView.updateState (http://localhost:8069/web/content/541-ad2a281/web.assets_backend.js:5414:2)
The actual locations of the error is at the access of node.parentNode at line 9 of dom.js
exports.parentNode = function(node) {
let parent = node.parentNode
return parent.nodeType == 11 ? parent.host : parent
}
called from line 11 of domcoord.js
function scrollRectIntoView(view, rect) {
let scrollThreshold = view.someProp(“scrollThreshold”) || 0, scrollMargin = view.someProp(“scrollMargin”)
if (scrollMargin == null) scrollMargin = 5
for (let parent = view.dom;; parent = parentNode(parent)) {
let atBody = parent == document.body
called from updateState() at line 137 of index.js
if (scrollToSelection) {
if (state.selection.node)
scrollRectIntoView(this, this.docView.domAfterPos(state.selection.from).getBoundingClientRect())
else
Evidently at the time of this call the div that the ProseMirror editor is anchored to has no element as a parent. The DOM is shown in this screen capture
The input to the above function is either an empty string or a stringified JSON representation of a ProseMirror document. That same JSON does work in the ProseMirror editor when constructing a new editor in the following way
let view = new pm_lib.pm_view.EditorView(this.$el[0], {
state: this._new_state(this.get('value')),
onAction: action =>
view.updateState(view.state.applyAction(action)),
})
so I know that the state I’m updating with is good.
I updated my node packages and the problem is indeed fixed. I see that it goes back to a fix you made on March 9th with a commit message that gets right to the point of my problem “Make sure parentNode doesn’t crash when reaching null”. I’ll be sure to keep my node packages more up-to-date and thank you again for fixing issues before I can even find them.
If I get the ProseMirror field pluin for Odoo working well and my employer is OK with open-sourcing the Odoo module then I’ll let you know. ProseMirror would add tremendous capabilities for Odoo form fields.