fix: better merge mark attributes for existing marks, fix #1039
This commit is contained in:
@@ -18,18 +18,41 @@ export const setMark: RawCommands['setMark'] = (typeOrName, attributes = {}) =>
|
|||||||
const { selection } = tr
|
const { selection } = tr
|
||||||
const { empty, ranges } = selection
|
const { empty, ranges } = selection
|
||||||
const type = getMarkType(typeOrName, state.schema)
|
const type = getMarkType(typeOrName, state.schema)
|
||||||
const oldAttributes = getMarkAttributes(state, type)
|
|
||||||
const newAttributes = {
|
|
||||||
...oldAttributes,
|
|
||||||
...attributes,
|
|
||||||
}
|
|
||||||
|
|
||||||
if (dispatch) {
|
if (dispatch) {
|
||||||
if (empty) {
|
if (empty) {
|
||||||
tr.addStoredMark(type.create(newAttributes))
|
const oldAttributes = getMarkAttributes(state, type)
|
||||||
|
|
||||||
|
tr.addStoredMark(type.create({
|
||||||
|
...oldAttributes,
|
||||||
|
...attributes,
|
||||||
|
}))
|
||||||
} else {
|
} else {
|
||||||
ranges.forEach(range => {
|
ranges.forEach(range => {
|
||||||
tr.addMark(range.$from.pos, range.$to.pos, type.create(newAttributes))
|
const from = range.$from.pos
|
||||||
|
const to = range.$to.pos
|
||||||
|
|
||||||
|
state.doc.nodesBetween(from, to, (node, pos) => {
|
||||||
|
const trimmedFrom = Math.max(pos, from)
|
||||||
|
const trimmedTo = Math.min(pos + node.nodeSize, to)
|
||||||
|
const someHasMark = node.marks.find(mark => mark.type === type)
|
||||||
|
|
||||||
|
// if there is already a mark of this type
|
||||||
|
// we know that we have to merge its attributes
|
||||||
|
// otherwise we add a fresh new mark
|
||||||
|
if (someHasMark) {
|
||||||
|
node.marks.forEach(mark => {
|
||||||
|
if (type === mark.type) {
|
||||||
|
tr.addMark(trimmedFrom, trimmedTo, type.create({
|
||||||
|
...mark.attrs,
|
||||||
|
...attributes,
|
||||||
|
}))
|
||||||
|
}
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
tr.addMark(trimmedFrom, trimmedTo, type.create(attributes))
|
||||||
|
}
|
||||||
|
})
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -40,7 +40,10 @@ export const updateAttributes: RawCommands['updateAttributes'] = (typeOrName, at
|
|||||||
|
|
||||||
if (dispatch) {
|
if (dispatch) {
|
||||||
tr.selection.ranges.forEach(range => {
|
tr.selection.ranges.forEach(range => {
|
||||||
state.doc.nodesBetween(range.$from.pos, range.$to.pos, (node, pos) => {
|
const from = range.$from.pos
|
||||||
|
const to = range.$to.pos
|
||||||
|
|
||||||
|
state.doc.nodesBetween(from, to, (node, pos) => {
|
||||||
if (nodeType && nodeType === node.type) {
|
if (nodeType && nodeType === node.type) {
|
||||||
tr.setNodeMarkup(pos, undefined, {
|
tr.setNodeMarkup(pos, undefined, {
|
||||||
...node.attrs,
|
...node.attrs,
|
||||||
@@ -51,7 +54,10 @@ export const updateAttributes: RawCommands['updateAttributes'] = (typeOrName, at
|
|||||||
if (markType && node.marks.length) {
|
if (markType && node.marks.length) {
|
||||||
node.marks.forEach(mark => {
|
node.marks.forEach(mark => {
|
||||||
if (markType === mark.type) {
|
if (markType === mark.type) {
|
||||||
tr.addMark(pos, pos + node.nodeSize, markType.create({
|
const trimmedFrom = Math.max(pos, from)
|
||||||
|
const trimmedTo = Math.min(pos + node.nodeSize, to)
|
||||||
|
|
||||||
|
tr.addMark(trimmedFrom, trimmedTo, markType.create({
|
||||||
...mark.attrs,
|
...mark.attrs,
|
||||||
...attributes,
|
...attributes,
|
||||||
}))
|
}))
|
||||||
|
|||||||
Reference in New Issue
Block a user