parent
058a50285c
commit
abf3fab1b6
@ -164,6 +164,20 @@ const insertNegatedAttributes = (transaction, parent, currPos, negatedAttributes
|
|||||||
const doc = transaction.doc
|
const doc = transaction.doc
|
||||||
const ownClientId = doc.clientID
|
const ownClientId = doc.clientID
|
||||||
negatedAttributes.forEach((val, key) => {
|
negatedAttributes.forEach((val, key) => {
|
||||||
|
// check if we really need to create attributes
|
||||||
|
// (the attribute may be set the desired value already)
|
||||||
|
let n = currPos.right
|
||||||
|
while(
|
||||||
|
n !== null && (n.deleted === true || n.content.constructor === ContentFormat)
|
||||||
|
) {
|
||||||
|
if (!n.deleted && equalAttrs(currPos.currentAttributes.get(/** @type {ContentFormat} */ (n.content).key) ?? null, /** @type {ContentFormat} */ (n.content).value)) {
|
||||||
|
n.delete(transaction)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
n = n.right
|
||||||
|
}
|
||||||
|
|
||||||
|
// create negated attribute
|
||||||
const left = currPos.left
|
const left = currPos.left
|
||||||
const right = currPos.right
|
const right = currPos.right
|
||||||
const nextFormat = new Item(createID(ownClientId, getState(doc.store, ownClientId)), left, left && left.lastId, right, right && right.id, parent, null, new ContentFormat(key, val))
|
const nextFormat = new Item(createID(ownClientId, getState(doc.store, ownClientId)), left, left && left.lastId, right, right && right.id, parent, null, new ContentFormat(key, val))
|
||||||
|
@ -527,3 +527,41 @@ export const testUndoBlockBug = tc => {
|
|||||||
undoManager.redo() // {"text":{}}
|
undoManager.redo() // {"text":{}}
|
||||||
t.compare(design.toJSON(), { text: { blocks: { text: '4' } } })
|
t.compare(design.toJSON(), { text: { blocks: { text: '4' } } })
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Undo text formatting delete should not corrupt peer state.
|
||||||
|
*
|
||||||
|
* @see https://github.com/yjs/yjs/issues/392
|
||||||
|
* @param {t.TestCase} tc
|
||||||
|
*/
|
||||||
|
export const testUndoDeleteTextFormat = tc => {
|
||||||
|
const doc = new Y.Doc()
|
||||||
|
const text = doc.getText()
|
||||||
|
text.insert(0, 'Attack ships on fire off the shoulder of Orion.')
|
||||||
|
const doc2 = new Y.Doc()
|
||||||
|
const text2 = doc2.getText();
|
||||||
|
Y.applyUpdate(doc2, Y.encodeStateAsUpdate(doc))
|
||||||
|
const undoManager = new Y.UndoManager(text)
|
||||||
|
|
||||||
|
text.format(13, 7, { bold: true })
|
||||||
|
undoManager.stopCapturing()
|
||||||
|
Y.applyUpdate(doc2, Y.encodeStateAsUpdate(doc))
|
||||||
|
|
||||||
|
text.format(16, 4, { bold: null })
|
||||||
|
undoManager.stopCapturing()
|
||||||
|
Y.applyUpdate(doc2, Y.encodeStateAsUpdate(doc))
|
||||||
|
|
||||||
|
undoManager.undo()
|
||||||
|
Y.applyUpdate(doc2, Y.encodeStateAsUpdate(doc))
|
||||||
|
|
||||||
|
const expect = [
|
||||||
|
{ insert: 'Attack ships ' },
|
||||||
|
{
|
||||||
|
insert: 'on fire',
|
||||||
|
attributes: { bold: true }
|
||||||
|
},
|
||||||
|
{ insert: ' off the shoulder of Orion.' }
|
||||||
|
]
|
||||||
|
t.compare(text.toDelta(), expect)
|
||||||
|
t.compare(text2.toDelta(), expect)
|
||||||
|
}
|
||||||
|
@ -607,6 +607,35 @@ export const testFormattingBug = async tc => {
|
|||||||
console.log(text1.toDelta())
|
console.log(text1.toDelta())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Delete formatting should not leave redundant formatting items.
|
||||||
|
*
|
||||||
|
* @param {t.TestCase} tc
|
||||||
|
*/
|
||||||
|
export const testDeleteFormatting = tc => {
|
||||||
|
const doc = new Y.Doc()
|
||||||
|
const text = doc.getText()
|
||||||
|
text.insert(0, 'Attack ships on fire off the shoulder of Orion.')
|
||||||
|
|
||||||
|
const doc2 = new Y.Doc()
|
||||||
|
const text2 = doc2.getText()
|
||||||
|
Y.applyUpdate(doc2, Y.encodeStateAsUpdate(doc))
|
||||||
|
|
||||||
|
text.format(13, 7, { bold: true })
|
||||||
|
Y.applyUpdate(doc2, Y.encodeStateAsUpdate(doc))
|
||||||
|
|
||||||
|
text.format(16, 4, { bold: null })
|
||||||
|
Y.applyUpdate(doc2, Y.encodeStateAsUpdate(doc))
|
||||||
|
|
||||||
|
const expected = [
|
||||||
|
{ insert: 'Attack ships ' },
|
||||||
|
{ insert: 'on ', attributes: { bold: true } },
|
||||||
|
{ insert: 'fire off the shoulder of Orion.' }
|
||||||
|
]
|
||||||
|
t.compare(text.toDelta(), expected)
|
||||||
|
t.compare(text2.toDelta(), expected)
|
||||||
|
}
|
||||||
|
|
||||||
// RANDOM TESTS
|
// RANDOM TESTS
|
||||||
|
|
||||||
let charCounter = 0
|
let charCounter = 0
|
||||||
|
Loading…
x
Reference in New Issue
Block a user