ProseMirror / prosemirror

The ProseMirror WYSIWYM editor
http://prosemirror.net/
MIT License
7.61k stars 336 forks source link

How to avoid node attrs passing to children? #1480

Open zunsthy opened 1 month ago

zunsthy commented 1 month ago

For example, declare a node with background-color and a mark with background-color, the node background-color attribute will pass to the node's children.

const s = new Schema({
  nodes: schema.spec.nodes.append({ colorBlock: {
    content: 'block*', group: 'block',
    attrs: { bc: {} },
    toDOM(node) {
      return ['div', { style: `background-color: ${node.attrs.bc}` }, 0];
    },
    parseDOM: [{ tag: 'div', getAttrs(node) {
      const bc = node.style.backgroundColor;
      return bc ? { bc } : false;
    }}],
  }}),
  marks: schema.spec.marks.append({ colorText: {
    attrs: { bc: {} },
    toDOM(node) {
      return ['span', { style: `background-color: ${node.attrs.bc}`}];
    },
    parseDOM: [{  style: 'background-color',
      getAttrs: (bc) => (bc ? { bc } : false),
    }],
  }}),
});

Input HTML

<div style="background-color: red">abc<span style="background-color: blue">123</span></div>

Expected

<div style="background-color: red"><p>abc<span style="background-color: blue">123</span></p></div>

But get

<div style="background-color: red"><p><span style="background-color: red">abc</span><span style="background-color: blue">123</span></p></div>

The "colorBlock" node matches "red" color attribute, but I can't prevent the "red" color apply to the "abc" text as "colorText" mark.

marijnh commented 1 month ago

Style parse rules will match regardless of whether a node parse rule happened to already have looked at that style (in fact, the library doesn't even know that your getAttrs function looked at the style). I don't really see a way to make this work differently.