fix: Preserve the previous cursor position on `undo/redo` in StatusChatInput
This commit is contained in:
parent
6ab2873742
commit
0a857cbf9c
|
@ -288,6 +288,124 @@ Item {
|
||||||
verify(textWithPubKey.includes("@0x0JohnDoe"),
|
verify(textWithPubKey.includes("@0x0JohnDoe"),
|
||||||
"Expected @pubKey to replace @contactName")
|
"Expected @pubKey to replace @contactName")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Scenario: The user can undo and redo text changes
|
||||||
|
// Given the user has typed text in StatusChatInput
|
||||||
|
// """
|
||||||
|
// 123456789
|
||||||
|
// """
|
||||||
|
// When the user hits undo shortcut
|
||||||
|
// Then the last text change is reverted
|
||||||
|
// And the cursor position is reverted
|
||||||
|
// And the user can redo the text change
|
||||||
|
// And the cursor position is restored
|
||||||
|
function test_user_can_undo_and_redo_text_changes() {
|
||||||
|
testHelper.when_text_is_typed(statusChatInputKeyboardInputExpectedAsText,
|
||||||
|
"123456789", (typedText) => {})
|
||||||
|
|
||||||
|
keySequence(StandardKey.Undo)
|
||||||
|
compare(controlUnderTest.getPlainText(), "12345678")
|
||||||
|
compare(controlUnderTest.textInput.cursorPosition, 8)
|
||||||
|
|
||||||
|
keySequence(StandardKey.Redo)
|
||||||
|
compare(controlUnderTest.getPlainText(), "123456789")
|
||||||
|
compare(controlUnderTest.textInput.cursorPosition, 9)
|
||||||
|
|
||||||
|
keySequence(StandardKey.Undo)
|
||||||
|
keySequence(StandardKey.Undo)
|
||||||
|
keySequence(StandardKey.Undo)
|
||||||
|
compare(controlUnderTest.getPlainText(), "123456")
|
||||||
|
compare(controlUnderTest.textInput.cursorPosition, 6)
|
||||||
|
|
||||||
|
keySequence(StandardKey.Redo)
|
||||||
|
keySequence(StandardKey.Redo)
|
||||||
|
keySequence(StandardKey.Redo)
|
||||||
|
compare(controlUnderTest.getPlainText(), "123456789")
|
||||||
|
compare(controlUnderTest.textInput.cursorPosition, 9)
|
||||||
|
|
||||||
|
keyClick(Qt.Key_Backspace)
|
||||||
|
compare(controlUnderTest.getPlainText(), "12345678")
|
||||||
|
compare(controlUnderTest.textInput.cursorPosition, 8)
|
||||||
|
|
||||||
|
keySequence(StandardKey.Undo)
|
||||||
|
compare(controlUnderTest.getPlainText(), "123456789")
|
||||||
|
compare(controlUnderTest.textInput.cursorPosition, 9)
|
||||||
|
|
||||||
|
keyClick(Qt.Key_Backspace)
|
||||||
|
compare(controlUnderTest.getPlainText(), "12345678")
|
||||||
|
compare(controlUnderTest.textInput.cursorPosition, 8)
|
||||||
|
|
||||||
|
keySequence(StandardKey.Undo)
|
||||||
|
compare(controlUnderTest.getPlainText(), "123456789")
|
||||||
|
compare(controlUnderTest.textInput.cursorPosition, 9)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Scenario: The user can undo and redo text changes with selection
|
||||||
|
// Given the user has typed text in StatusChatInput
|
||||||
|
// """
|
||||||
|
// 123456789
|
||||||
|
// """
|
||||||
|
// And cursor is moved to the middle of the text, at position 5
|
||||||
|
// And the user selects and deletes text from position 5 to 3
|
||||||
|
// When the user hits undo shortcut
|
||||||
|
// Then the last text change is reverted
|
||||||
|
|
||||||
|
function test_user_can_undo_and_redo_text_changes_with_selection() {
|
||||||
|
testHelper.when_text_is_typed(statusChatInputKeyboardInputExpectedAsText,
|
||||||
|
"123456789", (typedText) => {})
|
||||||
|
|
||||||
|
controlUnderTest.textInput.cursorPosition = 5
|
||||||
|
controlUnderTest.textInput.select(5, 3)
|
||||||
|
keySequence(StandardKey.Delete)
|
||||||
|
compare(controlUnderTest.getPlainText(), "1236789")
|
||||||
|
|
||||||
|
keySequence(StandardKey.Undo)
|
||||||
|
compare(controlUnderTest.getPlainText(), "123456789")
|
||||||
|
compare(controlUnderTest.textInput.cursorPosition, 5)
|
||||||
|
|
||||||
|
|
||||||
|
controlUnderTest.textInput.select(5, 3)
|
||||||
|
keySequence(StandardKey.Delete)
|
||||||
|
compare(controlUnderTest.getPlainText(), "1236789")
|
||||||
|
|
||||||
|
keySequence(StandardKey.Undo)
|
||||||
|
compare(controlUnderTest.getPlainText(), "123456789")
|
||||||
|
compare(controlUnderTest.textInput.cursorPosition, 5)
|
||||||
|
|
||||||
|
controlUnderTest.textInput.cursorPosition = 4
|
||||||
|
controlUnderTest.textInput.select(4, 2)
|
||||||
|
keySequence(StandardKey.Delete)
|
||||||
|
compare(controlUnderTest.getPlainText(), "1256789")
|
||||||
|
|
||||||
|
keySequence(StandardKey.Undo)
|
||||||
|
compare(controlUnderTest.getPlainText(), "123456789")
|
||||||
|
compare(controlUnderTest.textInput.cursorPosition, 4)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Scenario: The user can undo and redo the entire text
|
||||||
|
// Given the user has typed text in StatusChatInput
|
||||||
|
// """
|
||||||
|
// 123456789
|
||||||
|
// """
|
||||||
|
// And the user selects and deletes the entire text
|
||||||
|
// When the user hits undo shortcut
|
||||||
|
// Then the last text change is reverted
|
||||||
|
function test_user_can_undo_and_redo_the_entire_text() {
|
||||||
|
testHelper.when_text_is_typed(statusChatInputKeyboardInputExpectedAsText,
|
||||||
|
"123456789", (typedText) => {})
|
||||||
|
|
||||||
|
controlUnderTest.textInput.select(0, 9)
|
||||||
|
keySequence(StandardKey.Delete)
|
||||||
|
compare(controlUnderTest.getPlainText(), "")
|
||||||
|
|
||||||
|
keySequence(StandardKey.Undo)
|
||||||
|
compare(controlUnderTest.getPlainText(), "123456789")
|
||||||
|
compare(controlUnderTest.textInput.cursorPosition, 9)
|
||||||
|
|
||||||
|
keySequence(StandardKey.Redo)
|
||||||
|
compare(controlUnderTest.getPlainText(), "")
|
||||||
|
compare(controlUnderTest.textInput.cursorPosition, 0)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
TestCase {
|
TestCase {
|
||||||
|
|
|
@ -122,25 +122,46 @@ Item {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function extrapolatePreviousCursorPosition() {
|
||||||
|
const previousText = root.textEdit.getText(0, root.textEdit.length)
|
||||||
|
const previousCursorPosition = root.textEdit.cursorPosition - root.textEdit.length + d.previousText.length
|
||||||
|
return previousCursorPosition
|
||||||
|
}
|
||||||
|
|
||||||
readonly property Connections textChangedConnection: Connections {
|
readonly property Connections textChangedConnection: Connections {
|
||||||
target: root.textEdit
|
target: root.textEdit
|
||||||
enabled: root.enabled && !d.aboutToChangeText
|
enabled: root.enabled && !d.aboutToChangeText
|
||||||
function onTextChanged() {
|
function onTextChanged() {
|
||||||
const unformattedText = root.textEdit.getText(0, root.textEdit.length)
|
const unformattedText = root.textEdit.getText(0, root.textEdit.length)
|
||||||
|
|
||||||
if(d.previousText !== unformattedText) {
|
if(d.previousText !== unformattedText) {
|
||||||
const newFormattedText = root.textEdit.text
|
const newFormattedText = root.textEdit.text
|
||||||
|
const newCursorPosition = root.textEdit.cursorPosition
|
||||||
|
|
||||||
const previousFormattedTextCopy = d.previousFormattedText
|
const previousFormattedTextCopy = d.previousFormattedText
|
||||||
|
const previousCursorPosition = d.extrapolatePreviousCursorPosition()
|
||||||
|
|
||||||
d.undoStack.push({
|
d.undoStack.push({
|
||||||
undo: function() {
|
undo: function() {
|
||||||
d.aboutToChangeText = true
|
d.aboutToChangeText = true
|
||||||
|
//restore
|
||||||
root.textEdit.text = previousFormattedTextCopy
|
root.textEdit.text = previousFormattedTextCopy
|
||||||
root.textEdit.cursorPosition = root.textEdit.length
|
root.textEdit.cursorPosition = previousCursorPosition
|
||||||
|
//snapshot
|
||||||
|
d.previousText = root.textEdit.getText(0, root.textEdit.length)
|
||||||
|
d.previousFormattedText = root.textEdit.text
|
||||||
|
|
||||||
d.aboutToChangeText = false
|
d.aboutToChangeText = false
|
||||||
},
|
},
|
||||||
redo: function() {
|
redo: function() {
|
||||||
d.aboutToChangeText = true
|
d.aboutToChangeText = true
|
||||||
|
//restore
|
||||||
root.textEdit.text = newFormattedText
|
root.textEdit.text = newFormattedText
|
||||||
root.textEdit.cursorPosition = root.textEdit.length
|
root.textEdit.cursorPosition = newCursorPosition
|
||||||
|
//snapshot
|
||||||
|
d.previousText = root.textEdit.getText(0, root.textEdit.length)
|
||||||
|
d.previousFormattedText = root.textEdit.text
|
||||||
|
|
||||||
d.aboutToChangeText = false
|
d.aboutToChangeText = false
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
Loading…
Reference in New Issue