Skip to content

Commit 5e63001

Browse files
committed
Fix undo selection behavior
1 parent f24bffe commit 5e63001

File tree

2 files changed

+37
-25
lines changed

2 files changed

+37
-25
lines changed

src/index.ts

Lines changed: 31 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -648,6 +648,14 @@ function undoUnorderedListStyle(text: string): UndoResult {
648648
}
649649
}
650650

651+
const prefix = (index: number, unorderedList: boolean): string => {
652+
if (unorderedList) {
653+
return '- '
654+
} else {
655+
return `${index + 1}. `
656+
}
657+
}
658+
651659
function listStyle(textarea: HTMLTextAreaElement, style: StyleArgs): SelectionRange {
652660
const noInitialSelection = textarea.selectionStart === textarea.selectionEnd
653661
let selectionStart = textarea.selectionStart
@@ -656,55 +664,59 @@ function listStyle(textarea: HTMLTextAreaElement, style: StyleArgs): SelectionRa
656664
// Select whole line
657665
expandSelectionToLine(textarea)
658666

659-
const prefix = (index: number): string => {
660-
if (style.unorderedList) {
661-
return '- '
662-
} else if (style.orderedList) {
663-
return `${index + 1}. `
664-
}
665-
return ''
666-
}
667-
668667
let selectedText = textarea.value.slice(textarea.selectionStart, textarea.selectionEnd)
669668

670669
// If the user intent was to do an undo, we will stop after this.
671670
// Otherwise, we will still undo to other list type to prevent list stacking
671+
let undoResultOpositeList: UndoResult
672672
let undoResult: UndoResult
673+
673674
if (style.orderedList) {
674675
undoResult = undoOrderedListStyle(selectedText)
675-
selectedText = undoUnorderedListStyle(undoResult.text).text
676+
undoResultOpositeList = undoUnorderedListStyle(undoResult.text)
677+
selectedText = undoResultOpositeList.text
676678
} else {
677679
undoResult = undoUnorderedListStyle(selectedText)
678-
selectedText = undoOrderedListStyle(undoResult.text).text
680+
undoResultOpositeList = undoOrderedListStyle(undoResult.text)
681+
selectedText = undoResultOpositeList.text
679682
}
680683

681684
const lines = selectedText.split('\n').map((value, index) => {
682-
return `${prefix(index)}${value}`
685+
return `${prefix(index, style.unorderedList)}${value}`
683686
})
684687

685688
const totalPrefixLength = lines.reduce((previousValue, currentValue, currentIndex) => {
686-
return previousValue + prefix(currentIndex).length
689+
return previousValue + prefix(currentIndex, style.unorderedList).length
690+
}, 0)
691+
692+
const totalPrefixLengthOpositeList = lines.reduce((previousValue, currentValue, currentIndex) => {
693+
return previousValue + prefix(currentIndex, !style.unorderedList).length
687694
}, 0)
688695

689696
if (undoResult.processed) {
690697
if (noInitialSelection) {
691-
selectionStart = Math.max(selectionStart - prefix(0).length, 0)
698+
selectionStart = Math.max(selectionStart - prefix(0, style.unorderedList).length, 0)
692699
selectionEnd = selectionStart
693700
} else {
694-
selectionStart = Math.max(selectionStart - prefix(0).length, 0)
695-
selectionEnd = selectionEnd - totalPrefixLength
701+
selectionStart = textarea.selectionStart
702+
selectionEnd = textarea.selectionEnd - prefix(0, style.unorderedList).length
696703
}
697704
return {text: undoResult.text, selectionStart, selectionEnd}
698705
}
699706

700707
const {newlinesToAppend, newlinesToPrepend} = newlinesToSurroundSelectedText(textarea)
701708

702709
if (noInitialSelection) {
703-
selectionStart = Math.max(selectionStart + prefix(0).length + newlinesToAppend.length, 0)
710+
selectionStart = Math.max(selectionStart + prefix(0, style.unorderedList).length + newlinesToAppend.length, 0)
704711
selectionEnd = selectionStart
705712
} else {
706-
selectionStart = Math.max(textarea.selectionStart + newlinesToAppend.length, 0)
707-
selectionEnd = textarea.selectionEnd + newlinesToAppend.length + totalPrefixLength
713+
if (undoResultOpositeList.processed) {
714+
selectionStart = Math.max(textarea.selectionStart + newlinesToAppend.length, 0)
715+
selectionEnd = textarea.selectionEnd + newlinesToAppend.length + totalPrefixLength - totalPrefixLengthOpositeList
716+
} else {
717+
selectionStart = Math.max(textarea.selectionStart + newlinesToAppend.length, 0)
718+
selectionEnd = textarea.selectionEnd + newlinesToAppend.length + totalPrefixLength
719+
}
708720
}
709721

710722
const text = newlinesToAppend + lines.join('\n') + newlinesToPrepend

test/test.js

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -598,19 +598,19 @@ describe('markdown-toolbar-element', function () {
598598
it('undo list if partial line is selected', function () {
599599
setVisualValue('One\n\n- T|w|o\n\nThree\n')
600600
clickToolbar('md-unordered-list')
601-
assert.equal('One\n\nT|w|o\n\nThree\n', visualValue())
601+
assert.equal('One\n\n|Two|\n\nThree\n', visualValue())
602602
})
603603

604604
it('undo two lines list if two lines are selected', function () {
605605
setVisualValue('|- One\n- Two|\n\nThree\n')
606606
clickToolbar('md-unordered-list')
607-
assert.equal('|One\nTwo|\n\nThree\n', visualValue())
607+
assert.equal('|One\nTwo\n\n|Three\n', visualValue())
608608
})
609609

610610
it('undo two lines list if 2 lines are partially selected', function () {
611611
setVisualValue('- O|ne\n- Tw|o\n\nThree\n')
612612
clickToolbar('md-unordered-list')
613-
assert.equal('O|ne\nTw|o\n\nThree\n', visualValue())
613+
assert.equal('|One\nTwo\n\n|Three\n', visualValue())
614614
})
615615
})
616616

@@ -619,14 +619,14 @@ describe('markdown-toolbar-element', function () {
619619
setVisualValue('One\n|Two\nThree|\n')
620620
clickToolbar('md-ordered-list')
621621
clickToolbar('md-unordered-list')
622-
assert.equal('One\n\n|- Two\n- Three\n|', visualValue())
622+
assert.equal('One\n\n|- Two\n- Three|\n', visualValue())
623623
})
624624

625625
it('does not stack list styles when selecting one line', function () {
626626
setVisualValue('One\n|Two|\nThree\n')
627627
clickToolbar('md-ordered-list')
628628
clickToolbar('md-unordered-list')
629-
assert.equal('One\n\n|- Two|\n\nThree', visualValue())
629+
assert.equal('One\n\n|- Two|\n\nThree\n', visualValue())
630630
})
631631

632632
it('turns line into list when you click the unordered list icon with selection', function () {
@@ -706,7 +706,7 @@ describe('markdown-toolbar-element', function () {
706706
it('undo an ordered list by selecting multiple styled lines', function () {
707707
setVisualValue('|1. One\n2. Two\n3. Three|\n')
708708
clickToolbar('md-ordered-list')
709-
assert.equal('|One\nTwo\nThree|\n', visualValue())
709+
assert.equal('|One\nTwo\nThree\n|', visualValue())
710710
})
711711
})
712712

0 commit comments

Comments
 (0)