Scenario 1
- user starts with an empty paragraph
- types “hello world”
- update colour of the entire text to blue (I’m using a mark to set text colour)
- user selects all text using ctrl+A or cmd+A
- user starts typing “cat”
Goal: “cat” to retain the mark of “hello world”. In the scenario above, “cat” is blue
Scenario 2
- user starts with an empty paragraph
- types “a”
- update colour of the entire text to blue (I’m using a mark to set text colour)
- user deletes “a”
- user starts typing “b”
Goal: “b” retains color mark.
I tried writing a plugin and uses appendTransaction
that will return tr.setStoredMark
when the selection is currently an instance of AllSelection
but it keeps getting ignored. After digging deeper, I find out that storedMarks
will only be used if it’s a TextSelection
Source code from prosemirror-state
new FieldDesc("storedMarks", {
init(config) { return config.storedMarks || null },
apply(tr, _marks, _old, state) { return state.selection.$cursor ? tr.storedMarks : null }
}),
I’m sure there are good reasons for it to behave that way. My question would be, how then would one go about achieving my goal as stated on scenario 1?
My current approach is hacky because it’s mutating the state directly instead of using transactions. This solves for both scenario 1 and 2.
function keepMarksAfterDeleteAll (): Plugin {
return new Plugin({
appendTransaction (transactions, prevState, curState) {
if (prevState.selection instanceof AllSelection && transactions[0].docChanged) {
curState.storedMarks = prevState.storedMarks || prevState.doc.resolve(1).marks()
} else if (curState.selection instanceof AllSelection) {
curState.storedMarks = curState.doc.resolve(1).marks()
}
}
})
}
is there a cleaner approach to this?