Truthy NodeView.dom causes toDOM to be ignored

TL;DR NodeSpec toDOM is only called if NodeView dom is null.

I don’t think this is an actual issue but I wanted to save somebody else sometime in case they do something similar to me.

I created an EmbedView to render iframes in my editor based on the footnote example. Here is the original View and spec.

const embedSpec = {
  inline: true,
  attrs: {
    src: {},
    title: {},
    frameborder: {},
    height: {},
    width: {},
    allowfullscreen: { default: false },
    allow: {}
  },
  atom: true,
  marks: '',
  group: 'inline',
  parseDOM: [{ tag: 'iframe[src]', getAttrs: getEmbedAttrs }],
  toDOM: node => ['iframe', node.attrs]
};

class EmbedView {
  constructor (node, view, getPos) {
    this.node = node;
    this.outerView = view;
    this.getPos = getPos;
   
    this.dom = document.createElement('iframe')
    this.dom.src = node.attrs.src
    // ... apply remaining attributes
  }
}

// ... editor definition
nodeViews: {
    embed (node, view, getPos) {
       return new EmbedView(node, view, getPos);
    }
}

This renders an iframe the way I want and everything is great.

Next I want to add a default class to all my iframes so I update the toDOM method.

const embedSpec = {
  // ...
  toDOM: node => ['iframe', { ...node.attrs, class: 'embed' }]
  // ...
}

And nothing happens! My iframe renders fine, but there is no class. So I add a console.log to toDOM and see nothing! My mind is boggled.

Then I think: “hmm, maybe toDOM is only called to if NodeView.dom is empty”

I update EmbedView.

class EmbedView {
  constructor (node, view, getPos) {
    this.node = node;
    this.outerView = view;
    this.getPos = getPos;
  }
}

The toDOM method is now called and my class is applied :tada: