CSS styles as marks vs decorations

So, background: I’m trying to implement a way for users to add a couple of properties best-represented as CSS styles (namely, text alignment and font-size, but others may come up as I work on this). This doesn’t seem like a good fit for nodes, because they could apply to a variety of dom elements, which leaves marks and decorations.

I got an implementation with decorations working pretty easily, both as node decorations and inline depending on selection. The problem: no history entries and thus no easy undo, and I don’t see a way around that.

Marks also seem like a decent fit, given that they can be inline or (going off the docs anyway) attached to a node. Except - I don’t get how a node with attached marks is serialized to DOM, particularly given that the MarkSpec toDOM function requires a DOM element or tag name of some sort, and styles can be applied to a variety of tags.

I suspect I’m not grasping something somewhere - help?

Yeah, decorations aren’t great for this. Those also don’t get preserved on copy-paste or drag-drop. Alignment is probably best done as an attribute on textblock nodes. Font size, if it can apply to any stretch of text, seems similar to emphasis, and could be a mark.

Thanks for the quick reply! Okay, definitely sounds like decorations aren’t the way to go.

I suppose spans with style attributes for the marks that can be inline works - some part of my brain feels like it’s ‘tidier’ if it’s collapsed down when possible (like if a whole block is affected, moving the attribute to the block tag instead of having a span nested inside a block), but the nested version probably more accurately conveys user actions.

Guessing that at the node level, I’d have to reimplement all the blocks that can take alignment tags, yeah?

Yes, but these are simple declarative definitions so there’s not a whole lot to reimplement.

True enough! That said, it seems like there’s an issue using style parse rules in a node schema - on the initial document parse, it hits this line of code and then errors, because there’s no mark associated with the rule (just a node instead). It can be worked around with a tag rule that checks the styles in getAttrs(), but it took some digging to figure out what was wrong with my spec.

Oh, indeed, that is something the documentation should definitely mention. Add in this patch.