diff --git a/src/index.ts b/src/index.ts index 87162e7..b15b41b 100644 --- a/src/index.ts +++ b/src/index.ts @@ -417,6 +417,30 @@ function insertText(textarea: HTMLTextAreaElement, {text, selectionStart, select } } +function undoOrderedListStyle(textarea: HTMLTextAreaElement): string[] { + const text = textarea.value.slice(textarea.selectionStart, textarea.selectionEnd) + const lines = text.split('\n') + const orderedListRegex = /^\d+\.\s+/ + const result = lines + const shouldUndoOrderedList = lines.every(line => orderedListRegex.test(line)) + if (shouldUndoOrderedList) { + return lines.map(line => line.replace(orderedListRegex, '')) + } + return result +} + +function undoUnorderedListStyle(textarea: HTMLTextAreaElement): string[] { + const text = textarea.value.slice(textarea.selectionStart, textarea.selectionEnd) + const lines = text.split('\n') + const unorderedListPrefix = '- ' + const shouldUndoUnorderedList = lines.every(line => line.startsWith(unorderedListPrefix)) + const result = lines + if (shouldUndoUnorderedList) { + return lines.map(line => line.slice(unorderedListPrefix.length, line.length)) + } + return result +} + function styleSelectedText(textarea: HTMLTextAreaElement, styleArgs: StyleArgs) { const text = textarea.value.slice(textarea.selectionStart, textarea.selectionEnd) @@ -568,7 +592,7 @@ function multilineStyle(textarea: HTMLTextAreaElement, arg: StyleArgs) { let text = textarea.value.slice(textarea.selectionStart, textarea.selectionEnd) let selectionStart = textarea.selectionStart let selectionEnd = textarea.selectionEnd - const lines = text.split('\n') + const lines = undoOrderedListStyle(textarea) const undoStyle = lines.every(line => line.startsWith(prefix) && line.endsWith(suffix)) if (undoStyle) { @@ -594,7 +618,6 @@ function orderedList(textarea: HTMLTextAreaElement): SelectionRange { let selectionStart let text = textarea.value.slice(textarea.selectionStart, textarea.selectionEnd) let textToUnstyle = text - let lines = text.split('\n') let startOfLine, endOfLine if (noInitialSelection) { const linesBefore = textarea.value.slice(0, textarea.selectionStart).split(/\n/) @@ -602,6 +625,7 @@ function orderedList(textarea: HTMLTextAreaElement): SelectionRange { endOfLine = wordSelectionEnd(textarea.value, textarea.selectionStart, true) textToUnstyle = textarea.value.slice(startOfLine, endOfLine) } + let lines = undoUnorderedListStyle(textarea) const linesToUnstyle = textToUnstyle.split('\n') const undoStyling = linesToUnstyle.every(line => orderedListRegex.test(line)) diff --git a/test/test.js b/test/test.js index ab8915e..b2d74e3 100644 --- a/test/test.js +++ b/test/test.js @@ -485,6 +485,20 @@ describe('markdown-toolbar-element', function () { }) describe('lists', function () { + it('does not stack list styles when selecting multiple lines', function () { + setVisualValue('One\n|Two\nThree|\n') + clickToolbar('md-ordered-list') + clickToolbar('md-unordered-list') + assert.equal('One\n\n|- Two\n- Three|\n', visualValue()) + }) + + it('does not stack list styles when selecting one line', function () { + setVisualValue('One\n|Two|\nThree|\n') + clickToolbar('md-ordered-list') + clickToolbar('md-unordered-list') + assert.equal('One\n\n|- Two\n- Three|\n', visualValue()) + }) + it('turns line into list when you click the unordered list icon with selection', function () { setVisualValue('One\n|Two|\nThree\n') clickToolbar('md-unordered-list')