From a2196ce0e9a60472e17a38ce55565622c4dce263 Mon Sep 17 00:00:00 2001 From: Patrick Dinger <121539+paxos@users.noreply.github.com> Date: Mon, 29 Nov 2021 13:28:20 -1000 Subject: [PATCH 01/27] Add testsuite for unordered list --- test/test.js | 45 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 45 insertions(+) diff --git a/test/test.js b/test/test.js index ab8915e..02ec7f8 100644 --- a/test/test.js +++ b/test/test.js @@ -484,6 +484,51 @@ describe('markdown-toolbar-element', function () { }) }) + describe('unordered list', function () { + it('turns line into list if cursor at end of line', function () { + setVisualValue('One\nTwo|\nThree\n') + clickToolbar('md-unordered-list') + assert.equal('One\n\n- Two|\n\nThree\n', visualValue()) + }) + + it('turns line into list if cursor at end of document', function () { + setVisualValue('One\nTwo\nThree|') + clickToolbar('md-unordered-list') + assert.equal('One\nTwo\n\n- Three|', visualValue()) + }) + + it('turns line into list if cursor at beginning of line', function () { + setVisualValue('One\n|Two\nThree\n') + clickToolbar('md-unordered-list') + assert.equal('One\n\n- |Two\n\nThree\n', visualValue()) + }) + + it('turns line into list if cursor at middle of line', function () { + setVisualValue('One\nT|wo\nThree\n') + clickToolbar('md-unordered-list') + assert.equal('One\n\n- T|wo\n\nThree\n', visualValue()) + }) + + it('turns selection into list if partial line is selected', function () { + setVisualValue('One\nT|w|o\nThree\n') + clickToolbar('md-unordered-list') + assert.equal('One\n\n- T|w|o\n\nThree\n', visualValue()) + }) + + it('turns selection into list if two lines are selected', function () { + setVisualValue('|One\nTwo|\nThree\n') + clickToolbar('md-unordered-list') + assert.equal('|- One\n- Two|\n\nThree\n', visualValue()) + }) + + it('turns selection into list if 2 lines are partially selected', function () { + setVisualValue('O|ne\nTw|o\nThree\n') + clickToolbar('md-unordered-list') + assert.equal('- O|ne\n- Tw|o\n\nThree\n', visualValue()) + }) + // TODO: Add undo test for all of this + }) + describe('lists', function () { it('turns line into list when you click the unordered list icon with selection', function () { setVisualValue('One\n|Two|\nThree\n') From 88b1a76b88c2ec05a9de0248eef626345b04181c Mon Sep 17 00:00:00 2001 From: Patrick Dinger <121539+paxos@users.noreply.github.com> Date: Mon, 29 Nov 2021 14:04:32 -1000 Subject: [PATCH 02/27] Generalize tests for both list types --- test/test.js | 55 ++++++++++++++++++++++++++++++++++++++-------------- 1 file changed, 40 insertions(+), 15 deletions(-) diff --git a/test/test.js b/test/test.js index 02ec7f8..7f76577 100644 --- a/test/test.js +++ b/test/test.js @@ -32,6 +32,17 @@ describe('markdown-toolbar-element', function () { toolbar.querySelector(selector).click() } + function assertNormalizedList(str, ordered = false) { + let listIndex = 0 + const stringToCompare = ordered + ? str.replace('- ', (matched, index, original) => { + ++listIndex + return `${listIndex}. ` + }) + : str + assert.equal(stringToCompare, visualValue()) + } + function visualValue() { const textarea = document.querySelector('textarea') const before = textarea.value.slice(0, textarea.selectionStart) @@ -484,49 +495,63 @@ describe('markdown-toolbar-element', function () { }) }) - describe('unordered list', function () { + function listTests(toolbarItem, orderedList) { it('turns line into list if cursor at end of line', function () { setVisualValue('One\nTwo|\nThree\n') - clickToolbar('md-unordered-list') - assert.equal('One\n\n- Two|\n\nThree\n', visualValue()) + clickToolbar(toolbarItem) + assertNormalizedList('One\n\n- Two|\n\nThree\n', orderedList) }) it('turns line into list if cursor at end of document', function () { setVisualValue('One\nTwo\nThree|') - clickToolbar('md-unordered-list') - assert.equal('One\nTwo\n\n- Three|', visualValue()) + clickToolbar(toolbarItem) + assertNormalizedList('One\nTwo\n\n- Three|', orderedList) }) it('turns line into list if cursor at beginning of line', function () { setVisualValue('One\n|Two\nThree\n') - clickToolbar('md-unordered-list') - assert.equal('One\n\n- |Two\n\nThree\n', visualValue()) + clickToolbar(toolbarItem) + assertNormalizedList('One\n\n- |Two\n\nThree\n', orderedList) }) it('turns line into list if cursor at middle of line', function () { setVisualValue('One\nT|wo\nThree\n') - clickToolbar('md-unordered-list') - assert.equal('One\n\n- T|wo\n\nThree\n', visualValue()) + clickToolbar(toolbarItem) + assertNormalizedList('One\n\n- T|wo\n\nThree\n', orderedList) + }) + + it('turns selection into list if line is selected', function () { + setVisualValue('One\n|Two|\nThree\n') + clickToolbar(toolbarItem) + assertNormalizedList('One\n\n- |Two|\n\nThree\n', orderedList) }) it('turns selection into list if partial line is selected', function () { setVisualValue('One\nT|w|o\nThree\n') - clickToolbar('md-unordered-list') - assert.equal('One\n\n- T|w|o\n\nThree\n', visualValue()) + clickToolbar(toolbarItem) + assertNormalizedList('One\n\n- T|w|o\n\nThree\n', orderedList) }) it('turns selection into list if two lines are selected', function () { setVisualValue('|One\nTwo|\nThree\n') - clickToolbar('md-unordered-list') - assert.equal('|- One\n- Two|\n\nThree\n', visualValue()) + clickToolbar(toolbarItem) + assertNormalizedList('|- One\n- Two|\n\nThree\n', orderedList) }) it('turns selection into list if 2 lines are partially selected', function () { setVisualValue('O|ne\nTw|o\nThree\n') - clickToolbar('md-unordered-list') - assert.equal('- O|ne\n- Tw|o\n\nThree\n', visualValue()) + clickToolbar(toolbarItem) + assertNormalizedList('- O|ne\n- Tw|o\n\nThree\n', orderedList) }) // TODO: Add undo test for all of this + } + + describe('unordered list', function () { + listTests('md-unordered-list', false) + }) + + describe('ordered list', function () { + listTests('md-ordered-list', true) }) describe('lists', function () { From 68a69500d8bd83b47a4d5431bebad1261c540fbe Mon Sep 17 00:00:00 2001 From: Patrick Dinger <121539+paxos@users.noreply.github.com> Date: Mon, 29 Nov 2021 18:33:55 -1000 Subject: [PATCH 03/27] Update test names --- test/test.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/test/test.js b/test/test.js index 7f76577..2b15db3 100644 --- a/test/test.js +++ b/test/test.js @@ -526,19 +526,19 @@ describe('markdown-toolbar-element', function () { assertNormalizedList('One\n\n- |Two|\n\nThree\n', orderedList) }) - it('turns selection into list if partial line is selected', function () { + it('turns line into list if partial line is selected', function () { setVisualValue('One\nT|w|o\nThree\n') clickToolbar(toolbarItem) assertNormalizedList('One\n\n- T|w|o\n\nThree\n', orderedList) }) - it('turns selection into list if two lines are selected', function () { + it('turns two lines into list if two lines are selected', function () { setVisualValue('|One\nTwo|\nThree\n') clickToolbar(toolbarItem) assertNormalizedList('|- One\n- Two|\n\nThree\n', orderedList) }) - it('turns selection into list if 2 lines are partially selected', function () { + it('turns two lines into list if 2 lines are partially selected', function () { setVisualValue('O|ne\nTw|o\nThree\n') clickToolbar(toolbarItem) assertNormalizedList('- O|ne\n- Tw|o\n\nThree\n', orderedList) From 97332349ba12d8b282a13cac479dafd2df445aa2 Mon Sep 17 00:00:00 2001 From: Patrick Dinger <121539+paxos@users.noreply.github.com> Date: Tue, 30 Nov 2021 08:55:47 -1000 Subject: [PATCH 04/27] Revert "Generalize tests for both list types" This reverts commit 88b1a76b88c2ec05a9de0248eef626345b04181c. --- test/test.js | 55 ++++++++++++++-------------------------------------- 1 file changed, 15 insertions(+), 40 deletions(-) diff --git a/test/test.js b/test/test.js index 2b15db3..2765b42 100644 --- a/test/test.js +++ b/test/test.js @@ -32,17 +32,6 @@ describe('markdown-toolbar-element', function () { toolbar.querySelector(selector).click() } - function assertNormalizedList(str, ordered = false) { - let listIndex = 0 - const stringToCompare = ordered - ? str.replace('- ', (matched, index, original) => { - ++listIndex - return `${listIndex}. ` - }) - : str - assert.equal(stringToCompare, visualValue()) - } - function visualValue() { const textarea = document.querySelector('textarea') const before = textarea.value.slice(0, textarea.selectionStart) @@ -495,63 +484,49 @@ describe('markdown-toolbar-element', function () { }) }) - function listTests(toolbarItem, orderedList) { + describe('unordered list', function () { it('turns line into list if cursor at end of line', function () { setVisualValue('One\nTwo|\nThree\n') - clickToolbar(toolbarItem) - assertNormalizedList('One\n\n- Two|\n\nThree\n', orderedList) + clickToolbar('md-unordered-list') + assert.equal('One\n\n- Two|\n\nThree\n', visualValue()) }) it('turns line into list if cursor at end of document', function () { setVisualValue('One\nTwo\nThree|') - clickToolbar(toolbarItem) - assertNormalizedList('One\nTwo\n\n- Three|', orderedList) + clickToolbar('md-unordered-list') + assert.equal('One\nTwo\n\n- Three|', visualValue()) }) it('turns line into list if cursor at beginning of line', function () { setVisualValue('One\n|Two\nThree\n') - clickToolbar(toolbarItem) - assertNormalizedList('One\n\n- |Two\n\nThree\n', orderedList) + clickToolbar('md-unordered-list') + assert.equal('One\n\n- |Two\n\nThree\n', visualValue()) }) it('turns line into list if cursor at middle of line', function () { setVisualValue('One\nT|wo\nThree\n') - clickToolbar(toolbarItem) - assertNormalizedList('One\n\n- T|wo\n\nThree\n', orderedList) - }) - - it('turns selection into list if line is selected', function () { - setVisualValue('One\n|Two|\nThree\n') - clickToolbar(toolbarItem) - assertNormalizedList('One\n\n- |Two|\n\nThree\n', orderedList) + clickToolbar('md-unordered-list') + assert.equal('One\n\n- T|wo\n\nThree\n', visualValue()) }) it('turns line into list if partial line is selected', function () { setVisualValue('One\nT|w|o\nThree\n') - clickToolbar(toolbarItem) - assertNormalizedList('One\n\n- T|w|o\n\nThree\n', orderedList) + clickToolbar('md-unordered-list') + assert.equal('One\n\n- T|w|o\n\nThree\n', visualValue()) }) it('turns two lines into list if two lines are selected', function () { setVisualValue('|One\nTwo|\nThree\n') - clickToolbar(toolbarItem) - assertNormalizedList('|- One\n- Two|\n\nThree\n', orderedList) + clickToolbar('md-unordered-list') + assert.equal('|- One\n- Two|\n\nThree\n', visualValue()) }) it('turns two lines into list if 2 lines are partially selected', function () { setVisualValue('O|ne\nTw|o\nThree\n') - clickToolbar(toolbarItem) - assertNormalizedList('- O|ne\n- Tw|o\n\nThree\n', orderedList) + clickToolbar('md-unordered-list') + assert.equal('- O|ne\n- Tw|o\n\nThree\n', visualValue()) }) // TODO: Add undo test for all of this - } - - describe('unordered list', function () { - listTests('md-unordered-list', false) - }) - - describe('ordered list', function () { - listTests('md-ordered-list', true) }) describe('lists', function () { From 6fd186ce3b683a1a97066291bd69dfd2d986fe9a Mon Sep 17 00:00:00 2001 From: Patrick Dinger <121539+paxos@users.noreply.github.com> Date: Tue, 30 Nov 2021 09:09:34 -1000 Subject: [PATCH 05/27] Add more tests --- test/test.js | 43 ++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 42 insertions(+), 1 deletion(-) diff --git a/test/test.js b/test/test.js index 2765b42..bc73805 100644 --- a/test/test.js +++ b/test/test.js @@ -526,7 +526,48 @@ describe('markdown-toolbar-element', function () { clickToolbar('md-unordered-list') assert.equal('- O|ne\n- Tw|o\n\nThree\n', visualValue()) }) - // TODO: Add undo test for all of this + + it('undo list if cursor at end of line', function () { + setVisualValue('One\n\n- Two|\n\nThree\n') + clickToolbar('md-unordered-list') + assert.equal('One\nTwo|\nThree\n', visualValue()) + }) + + it('undo list if cursor at end of document', function () { + setVisualValue('One\nTwo\n\n- Three|') + clickToolbar('md-unordered-list') + assert.equal('One\nTwo\nThree|', visualValue()) + }) + + it('undo list if cursor at beginning of line', function () { + setVisualValue('One\n\n- |Two\n\nThree\n') + clickToolbar('md-unordered-list') + assert.equal('One\n|Two\nThree\n', visualValue()) + }) + + it('undo list if cursor at middle of line', function () { + setVisualValue('One\n\n- T|wo\n\nThree\n') + clickToolbar('md-unordered-list') + assert.equal('One\nT|wo\nThree\n', visualValue()) + }) + + it('undo list if partial line is selected', function () { + setVisualValue('One\n\n- T|w|o\n\nThree\n') + clickToolbar('md-unordered-list') + assert.equal('One\nT|w|o\nThree\n', visualValue()) + }) + + it('undo two lines list if two lines are selected', function () { + setVisualValue('|- One\n- Two|\n\nThree\n') + clickToolbar('md-unordered-list') + assert.equal('|One\nTwo|\nThree\n', visualValue()) + }) + + it('undo two lines list if 2 lines are partially selected', function () { + setVisualValue('- O|ne\n- Tw|o\n\nThree\n') + clickToolbar('md-unordered-list') + assert.equal('O|ne\nTw|o\nThree\n', visualValue()) + }) }) describe('lists', function () { From ec5f52a3dd8f3b9ed8c5d7cc1e4b0e98ad230db6 Mon Sep 17 00:00:00 2001 From: Patrick Dinger <121539+paxos@users.noreply.github.com> Date: Tue, 30 Nov 2021 11:27:37 -1000 Subject: [PATCH 06/27] Add new behavior for no selection --- src/index.ts | 93 ++++++++++++++++++++++++++++++++++++++++++++++++++-- test/test.js | 14 ++++++++ 2 files changed, 104 insertions(+), 3 deletions(-) diff --git a/src/index.ts b/src/index.ts index 87162e7..23e4ce9 100644 --- a/src/index.ts +++ b/src/index.ts @@ -79,6 +79,7 @@ type Style = { replaceNext?: string scanFor?: string orderedList?: boolean + unorderedList?: boolean prefixSpace?: boolean } @@ -205,7 +206,7 @@ if (!window.customElements.get('md-image')) { class MarkdownUnorderedListButtonElement extends MarkdownButtonElement { constructor() { super() - styles.set(this, {prefix: '- ', multiline: true, surroundWithNewlines: true}) + styles.set(this, {prefix: '- ', multiline: true, unorderedList: true}) } } @@ -421,8 +422,8 @@ function styleSelectedText(textarea: HTMLTextAreaElement, styleArgs: StyleArgs) const text = textarea.value.slice(textarea.selectionStart, textarea.selectionEnd) let result - if (styleArgs.orderedList) { - result = orderedList(textarea) + if (styleArgs.orderedList || styleArgs.unorderedList) { + result = listStyle(textarea, styleArgs) } else if (styleArgs.multiline && isMultipleLines(text)) { result = multilineStyle(textarea, styleArgs) } else { @@ -432,6 +433,17 @@ function styleSelectedText(textarea: HTMLTextAreaElement, styleArgs: StyleArgs) insertText(textarea, result) } +export function selectionIndexForLine(lines: string[], line: number): SelectionRange | null { + let counter = 0 + for (let index = 0; index < lines.length; index++) { + if (index === line) { + return {selectionStart: counter, selectionEnd: counter + lines[index].length, text: ''} + } + counter += lines[index].length + 1 + } + return null +} + function expandSelectedText( textarea: HTMLTextAreaElement, prefixToUse: string, @@ -587,6 +599,79 @@ function multilineStyle(textarea: HTMLTextAreaElement, arg: StyleArgs) { return {text, selectionStart, selectionEnd} } +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 listStyle(textarea: HTMLTextAreaElement, style: StyleArgs): SelectionRange { + const noInitialSelection = textarea.selectionStart === textarea.selectionEnd + let selectionStart = textarea.selectionStart + let selectionEnd = textarea.selectionEnd + let lines: string[] = [] + let text = textarea.value.slice(textarea.selectionStart, textarea.selectionEnd) + let startOfLine, endOfLine + + undoOrderedListStyle(textarea) + undoUnorderedListStyle(textarea) + + const prefix = '- ' + + //let selectedText = expandSelectedText(textarea, prefix, '', style.multiline) + + // Style only the selected line + if (noInitialSelection) { + const linesBefore = textarea.value.slice(0, textarea.selectionStart).split(/\n/) + lines = textarea.value.split('\n') + + const currentLine = linesBefore.length - 1 + const currentLineText = lines[currentLine] + + // Select whole line + const range = selectionIndexForLine(lines, currentLine) + if (range) { + textarea.selectionStart = range.selectionStart ?? 0 + textarea.selectionEnd = range.selectionEnd ?? 0 + } + + // line with caret + //lines[linesBefore.length - 1] = prefix + linesBefore[linesBefore.length - 1] + + text = prefix + currentLineText + + // if (style.surroundWithNewlines) { + const {newlinesToAppend, newlinesToPrepend} = newlinesToSurroundSelectedText(textarea) + selectionStart = selectionStart + prefix.length + 1 + selectionEnd = selectionStart + text = newlinesToAppend + text + newlinesToPrepend + + return {text, selectionStart, selectionEnd} + } + + text = lines.join('\n') + + return {text, selectionStart, selectionEnd} +} + function orderedList(textarea: HTMLTextAreaElement): SelectionRange { const orderedListRegex = /^\d+\.\s+/ const noInitialSelection = textarea.selectionStart === textarea.selectionEnd @@ -638,6 +723,7 @@ interface StyleArgs { scanFor: string surroundWithNewlines: boolean orderedList: boolean + unorderedList: boolean trimFirst: boolean } @@ -668,6 +754,7 @@ function applyStyle(button: Element, stylesToApply: Style) { scanFor: '', surroundWithNewlines: false, orderedList: false, + unorderedList: false, trimFirst: false } diff --git a/test/test.js b/test/test.js index bc73805..98a5256 100644 --- a/test/test.js +++ b/test/test.js @@ -571,6 +571,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') From feacc96faa8d6671a09a6c69152ba50cd54e6666 Mon Sep 17 00:00:00 2001 From: Patrick Dinger <121539+paxos@users.noreply.github.com> Date: Tue, 30 Nov 2021 11:56:05 -1000 Subject: [PATCH 07/27] Add expand line selection logic --- src/index.ts | 31 ++++++++++++++++++++++++------- 1 file changed, 24 insertions(+), 7 deletions(-) diff --git a/src/index.ts b/src/index.ts index 23e4ce9..9ba0a21 100644 --- a/src/index.ts +++ b/src/index.ts @@ -433,7 +433,22 @@ function styleSelectedText(textarea: HTMLTextAreaElement, styleArgs: StyleArgs) insertText(textarea, result) } -export function selectionIndexForLine(lines: string[], line: number): SelectionRange | null { +function expandSelectionToLine(textarea: HTMLTextAreaElement) { + const lines = textarea.value.split('\n') + let counter = 0 + for (let index = 0; index < lines.length; index++) { + const lineLength = lines[index].length + 1 + if (textarea.selectionStart >= counter && textarea.selectionStart <= counter + lineLength) { + textarea.selectionStart = counter + } + if (textarea.selectionEnd > counter && textarea.selectionEnd <= counter + lineLength) { + textarea.selectionEnd = counter + lineLength + } + counter += lineLength + } +} + +function selectionIndexForLine(lines: string[], line: number): SelectionRange | null { let counter = 0 for (let index = 0; index < lines.length; index++) { if (index === line) { @@ -636,7 +651,9 @@ function listStyle(textarea: HTMLTextAreaElement, style: StyleArgs): SelectionRa const prefix = '- ' - //let selectedText = expandSelectedText(textarea, prefix, '', style.multiline) + // Expand selection to full lines + + expandSelectionToLine(textarea) // Style only the selected line if (noInitialSelection) { @@ -648,10 +665,10 @@ function listStyle(textarea: HTMLTextAreaElement, style: StyleArgs): SelectionRa // Select whole line const range = selectionIndexForLine(lines, currentLine) - if (range) { - textarea.selectionStart = range.selectionStart ?? 0 - textarea.selectionEnd = range.selectionEnd ?? 0 - } + // if (range) { + // textarea.selectionStart = range.selectionStart ?? 0 + // textarea.selectionEnd = range.selectionEnd ?? 0 + // } // line with caret //lines[linesBefore.length - 1] = prefix + linesBefore[linesBefore.length - 1] @@ -661,7 +678,7 @@ function listStyle(textarea: HTMLTextAreaElement, style: StyleArgs): SelectionRa // if (style.surroundWithNewlines) { const {newlinesToAppend, newlinesToPrepend} = newlinesToSurroundSelectedText(textarea) selectionStart = selectionStart + prefix.length + 1 - selectionEnd = selectionStart + selectionEnd = selectionEnd + prefix.length + 1 text = newlinesToAppend + text + newlinesToPrepend return {text, selectionStart, selectionEnd} From 95450156eaaa972a790a4988b7d05fe83b3bf57b Mon Sep 17 00:00:00 2001 From: Patrick Dinger <121539+paxos@users.noreply.github.com> Date: Tue, 30 Nov 2021 12:53:27 -1000 Subject: [PATCH 08/27] Make lists work --- src/index.ts | 50 ++++++++++++++++---------------------------------- test/test.js | 2 +- 2 files changed, 17 insertions(+), 35 deletions(-) diff --git a/src/index.ts b/src/index.ts index 9ba0a21..86565be 100644 --- a/src/index.ts +++ b/src/index.ts @@ -438,11 +438,11 @@ function expandSelectionToLine(textarea: HTMLTextAreaElement) { let counter = 0 for (let index = 0; index < lines.length; index++) { const lineLength = lines[index].length + 1 - if (textarea.selectionStart >= counter && textarea.selectionStart <= counter + lineLength) { + if (textarea.selectionStart >= counter && textarea.selectionStart < counter + lineLength) { textarea.selectionStart = counter } - if (textarea.selectionEnd > counter && textarea.selectionEnd <= counter + lineLength) { - textarea.selectionEnd = counter + lineLength + if (textarea.selectionEnd >= counter && textarea.selectionEnd < counter + lineLength) { + textarea.selectionEnd = counter + lineLength - 1 } counter += lineLength } @@ -642,49 +642,31 @@ function listStyle(textarea: HTMLTextAreaElement, style: StyleArgs): SelectionRa const noInitialSelection = textarea.selectionStart === textarea.selectionEnd let selectionStart = textarea.selectionStart let selectionEnd = textarea.selectionEnd - let lines: string[] = [] - let text = textarea.value.slice(textarea.selectionStart, textarea.selectionEnd) - let startOfLine, endOfLine undoOrderedListStyle(textarea) undoUnorderedListStyle(textarea) const prefix = '- ' - // Expand selection to full lines - + // Select whole line expandSelectionToLine(textarea) - // Style only the selected line - if (noInitialSelection) { - const linesBefore = textarea.value.slice(0, textarea.selectionStart).split(/\n/) - lines = textarea.value.split('\n') - - const currentLine = linesBefore.length - 1 - const currentLineText = lines[currentLine] - - // Select whole line - const range = selectionIndexForLine(lines, currentLine) - // if (range) { - // textarea.selectionStart = range.selectionStart ?? 0 - // textarea.selectionEnd = range.selectionEnd ?? 0 - // } + const selectedText = textarea.value.slice(textarea.selectionStart, textarea.selectionEnd) + const lines = selectedText.split('\n').map((value, index) => { + return `${prefix}${value}` + }) - // line with caret - //lines[linesBefore.length - 1] = prefix + linesBefore[linesBefore.length - 1] + const {newlinesToAppend, newlinesToPrepend} = newlinesToSurroundSelectedText(textarea) - text = prefix + currentLineText - - // if (style.surroundWithNewlines) { - const {newlinesToAppend, newlinesToPrepend} = newlinesToSurroundSelectedText(textarea) - selectionStart = selectionStart + prefix.length + 1 - selectionEnd = selectionEnd + prefix.length + 1 - text = newlinesToAppend + text + newlinesToPrepend - - return {text, selectionStart, selectionEnd} + if (noInitialSelection) { + selectionStart = Math.max(selectionStart + prefix.length + newlinesToAppend.length, 0) + selectionEnd = selectionStart + } else { + selectionStart = Math.max(selectionStart + prefix.length + newlinesToAppend.length, 0) + selectionEnd = selectionEnd + newlinesToAppend.length + prefix.length * lines.length } - text = lines.join('\n') + const text = newlinesToAppend + lines.join('\n') + newlinesToPrepend return {text, selectionStart, selectionEnd} } diff --git a/test/test.js b/test/test.js index 98a5256..0f90bb6 100644 --- a/test/test.js +++ b/test/test.js @@ -518,7 +518,7 @@ describe('markdown-toolbar-element', function () { it('turns two lines into list if two lines are selected', function () { setVisualValue('|One\nTwo|\nThree\n') clickToolbar('md-unordered-list') - assert.equal('|- One\n- Two|\n\nThree\n', visualValue()) + assert.equal('- |One\n- Two|\n\nThree\n', visualValue()) }) it('turns two lines into list if 2 lines are partially selected', function () { From 20dd2168046dd95e200b8711b08cb6000db12758 Mon Sep 17 00:00:00 2001 From: Patrick Dinger <121539+paxos@users.noreply.github.com> Date: Tue, 30 Nov 2021 13:15:17 -1000 Subject: [PATCH 09/27] Adjust tests --- src/index.ts | 55 +++++++++++++++++++++++++++++++++++++--------------- test/test.js | 14 ++++++------- 2 files changed, 46 insertions(+), 23 deletions(-) diff --git a/src/index.ts b/src/index.ts index 86565be..8790cae 100644 --- a/src/index.ts +++ b/src/index.ts @@ -614,28 +614,38 @@ function multilineStyle(textarea: HTMLTextAreaElement, arg: StyleArgs) { return {text, selectionStart, selectionEnd} } -function undoOrderedListStyle(textarea: HTMLTextAreaElement): string[] { - const text = textarea.value.slice(textarea.selectionStart, textarea.selectionEnd) +interface UndoResult { + text: string + processed: boolean +} +function undoOrderedListStyle(text: string): UndoResult { const lines = text.split('\n') const orderedListRegex = /^\d+\.\s+/ - const result = lines const shouldUndoOrderedList = lines.every(line => orderedListRegex.test(line)) + let result = lines if (shouldUndoOrderedList) { - return lines.map(line => line.replace(orderedListRegex, '')) + result = lines.map(line => line.replace(orderedListRegex, '')) + } + + return { + text: result.join('\n'), + processed: shouldUndoOrderedList } - return result } -function undoUnorderedListStyle(textarea: HTMLTextAreaElement): string[] { - const text = textarea.value.slice(textarea.selectionStart, textarea.selectionEnd) +function undoUnorderedListStyle(text: string): UndoResult { const lines = text.split('\n') const unorderedListPrefix = '- ' const shouldUndoUnorderedList = lines.every(line => line.startsWith(unorderedListPrefix)) - const result = lines + let result = lines if (shouldUndoUnorderedList) { - return lines.map(line => line.slice(unorderedListPrefix.length, line.length)) + result = lines.map(line => line.slice(unorderedListPrefix.length, line.length)) + } + + return { + text: result.join('\n'), + processed: shouldUndoUnorderedList } - return result } function listStyle(textarea: HTMLTextAreaElement, style: StyleArgs): SelectionRange { @@ -643,15 +653,29 @@ function listStyle(textarea: HTMLTextAreaElement, style: StyleArgs): SelectionRa let selectionStart = textarea.selectionStart let selectionEnd = textarea.selectionEnd - undoOrderedListStyle(textarea) - undoUnorderedListStyle(textarea) + // Select whole line + expandSelectionToLine(textarea) const prefix = '- ' - // Select whole line - expandSelectionToLine(textarea) + let selectedText = textarea.value.slice(textarea.selectionStart, textarea.selectionEnd) + + const undoOrderedListResult = undoOrderedListStyle(selectedText) + const undoUnorderedListResult = undoUnorderedListStyle(undoOrderedListResult.text) + + if (undoOrderedListResult.processed || undoUnorderedListResult.processed) { + if (noInitialSelection) { + selectionStart = Math.max(selectionStart - prefix.length, 0) + selectionEnd = selectionStart + } else { + selectionStart = Math.max(selectionStart - prefix.length, 0) + selectionEnd = selectionEnd + prefix.length // * lines.length + } + return {text: undoUnorderedListResult.text, selectionStart, selectionEnd} + } + + selectedText = undoUnorderedListResult.text - const selectedText = textarea.value.slice(textarea.selectionStart, textarea.selectionEnd) const lines = selectedText.split('\n').map((value, index) => { return `${prefix}${value}` }) @@ -667,7 +691,6 @@ function listStyle(textarea: HTMLTextAreaElement, style: StyleArgs): SelectionRa } const text = newlinesToAppend + lines.join('\n') + newlinesToPrepend - return {text, selectionStart, selectionEnd} } diff --git a/test/test.js b/test/test.js index 0f90bb6..fc7ea16 100644 --- a/test/test.js +++ b/test/test.js @@ -530,43 +530,43 @@ describe('markdown-toolbar-element', function () { it('undo list if cursor at end of line', function () { setVisualValue('One\n\n- Two|\n\nThree\n') clickToolbar('md-unordered-list') - assert.equal('One\nTwo|\nThree\n', visualValue()) + assert.equal('One\n\nTwo|\n\nThree\n', visualValue()) }) it('undo list if cursor at end of document', function () { setVisualValue('One\nTwo\n\n- Three|') clickToolbar('md-unordered-list') - assert.equal('One\nTwo\nThree|', visualValue()) + assert.equal('One\nTwo\n\nThree|', visualValue()) }) it('undo list if cursor at beginning of line', function () { setVisualValue('One\n\n- |Two\n\nThree\n') clickToolbar('md-unordered-list') - assert.equal('One\n|Two\nThree\n', visualValue()) + assert.equal('One\n\n|Two\n\nThree\n', visualValue()) }) it('undo list if cursor at middle of line', function () { setVisualValue('One\n\n- T|wo\n\nThree\n') clickToolbar('md-unordered-list') - assert.equal('One\nT|wo\nThree\n', visualValue()) + assert.equal('One\n\nT|wo\n\nThree\n', visualValue()) }) it('undo list if partial line is selected', function () { setVisualValue('One\n\n- T|w|o\n\nThree\n') clickToolbar('md-unordered-list') - assert.equal('One\nT|w|o\nThree\n', visualValue()) + assert.equal('One\n\nT|w|o\n\nThree\n', visualValue()) }) it('undo two lines list if two lines are selected', function () { setVisualValue('|- One\n- Two|\n\nThree\n') clickToolbar('md-unordered-list') - assert.equal('|One\nTwo|\nThree\n', visualValue()) + assert.equal('|One\nTwo|\n\nThree\n', visualValue()) }) it('undo two lines list if 2 lines are partially selected', function () { setVisualValue('- O|ne\n- Tw|o\n\nThree\n') clickToolbar('md-unordered-list') - assert.equal('O|ne\nTw|o\nThree\n', visualValue()) + assert.equal('O|ne\nTw|o\n\nThree\n', visualValue()) }) }) From 69a48899213823f1272a132c88a584251396aaf0 Mon Sep 17 00:00:00 2001 From: Patrick Dinger <121539+paxos@users.noreply.github.com> Date: Tue, 30 Nov 2021 13:50:28 -1000 Subject: [PATCH 10/27] Add support for ordered list + tests --- src/index.ts | 35 +++++++++++++++++++++++------------ test/test.js | 44 ++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 67 insertions(+), 12 deletions(-) diff --git a/src/index.ts b/src/index.ts index 8790cae..983b78e 100644 --- a/src/index.ts +++ b/src/index.ts @@ -656,7 +656,14 @@ function listStyle(textarea: HTMLTextAreaElement, style: StyleArgs): SelectionRa // Select whole line expandSelectionToLine(textarea) - const prefix = '- ' + const prefix = (index: number): string => { + if (style.unorderedList) { + return '- ' + } else if (style.orderedList) { + return `${index + 1}. ` + } + return '' + } let selectedText = textarea.value.slice(textarea.selectionStart, textarea.selectionEnd) @@ -664,30 +671,34 @@ function listStyle(textarea: HTMLTextAreaElement, style: StyleArgs): SelectionRa const undoUnorderedListResult = undoUnorderedListStyle(undoOrderedListResult.text) if (undoOrderedListResult.processed || undoUnorderedListResult.processed) { - if (noInitialSelection) { - selectionStart = Math.max(selectionStart - prefix.length, 0) - selectionEnd = selectionStart - } else { - selectionStart = Math.max(selectionStart - prefix.length, 0) - selectionEnd = selectionEnd + prefix.length // * lines.length - } + // if (noInitialSelection) { + // selectionStart = Math.max(selectionStart - prefix.length, 0) + // selectionEnd = selectionStart + // } else { + // selectionStart = Math.max(selectionStart - prefix.length, 0) + // selectionEnd = selectionEnd + prefix.length // * lines.length + // } return {text: undoUnorderedListResult.text, selectionStart, selectionEnd} } selectedText = undoUnorderedListResult.text const lines = selectedText.split('\n').map((value, index) => { - return `${prefix}${value}` + return `${prefix(index)}${value}` }) + const totalPrefixLength = lines.reduce((previousValue, currentValue, currentIndex) => { + return previousValue + prefix(currentIndex).length + }, 0) + const {newlinesToAppend, newlinesToPrepend} = newlinesToSurroundSelectedText(textarea) if (noInitialSelection) { - selectionStart = Math.max(selectionStart + prefix.length + newlinesToAppend.length, 0) + selectionStart = Math.max(selectionStart + prefix(0).length + newlinesToAppend.length, 0) selectionEnd = selectionStart } else { - selectionStart = Math.max(selectionStart + prefix.length + newlinesToAppend.length, 0) - selectionEnd = selectionEnd + newlinesToAppend.length + prefix.length * lines.length + selectionStart = Math.max(selectionStart + prefix(0).length + newlinesToAppend.length, 0) + selectionEnd = selectionEnd + newlinesToAppend.length + totalPrefixLength } const text = newlinesToAppend + lines.join('\n') + newlinesToPrepend diff --git a/test/test.js b/test/test.js index fc7ea16..410d413 100644 --- a/test/test.js +++ b/test/test.js @@ -484,6 +484,50 @@ describe('markdown-toolbar-element', function () { }) }) + describe('ordered list', function () { + it('turns line into list if cursor at end of line', function () { + setVisualValue('One\nTwo|\nThree\n') + clickToolbar('md-ordered-list') + assert.equal('One\n\n1. Two|\n\nThree\n', visualValue()) + }) + + it('turns line into list if cursor at end of document', function () { + setVisualValue('One\nTwo\nThree|') + clickToolbar('md-ordered-list') + assert.equal('One\nTwo\n\n1. Three|', visualValue()) + }) + + it('turns line into list if cursor at beginning of line', function () { + setVisualValue('One\n|Two\nThree\n') + clickToolbar('md-ordered-list') + assert.equal('One\n\n1. |Two\n\nThree\n', visualValue()) + }) + + it('turns line into list if cursor at middle of line', function () { + setVisualValue('One\nT|wo\nThree\n') + clickToolbar('md-ordered-list') + assert.equal('One\n\n1. T|wo\n\nThree\n', visualValue()) + }) + + it('turns line into list if partial line is selected', function () { + setVisualValue('One\nT|w|o\nThree\n') + clickToolbar('md-ordered-list') + assert.equal('One\n\n1. T|w|o\n\nThree\n', visualValue()) + }) + + it('turns two lines into list if two lines are selected', function () { + setVisualValue('|One\nTwo|\nThree\n') + clickToolbar('md-ordered-list') + assert.equal('1. |One\n2. Two|\n\nThree\n', visualValue()) + }) + + it('turns two lines into list if 2 lines are partially selected', function () { + setVisualValue('O|ne\nTw|o\nThree\n') + clickToolbar('md-ordered-list') + assert.equal('1. O|ne\n2. Tw|o\n\nThree\n', visualValue()) + }) + }) + describe('unordered list', function () { it('turns line into list if cursor at end of line', function () { setVisualValue('One\nTwo|\nThree\n') From b43f99538ca49108af3646dd96faefebf65569f4 Mon Sep 17 00:00:00 2001 From: Patrick Dinger <121539+paxos@users.noreply.github.com> Date: Tue, 30 Nov 2021 14:06:06 -1000 Subject: [PATCH 11/27] Fix list stacking --- src/index.ts | 32 ++++++++++++++++++++------------ 1 file changed, 20 insertions(+), 12 deletions(-) diff --git a/src/index.ts b/src/index.ts index 983b78e..bff0c1b 100644 --- a/src/index.ts +++ b/src/index.ts @@ -667,21 +667,29 @@ function listStyle(textarea: HTMLTextAreaElement, style: StyleArgs): SelectionRa let selectedText = textarea.value.slice(textarea.selectionStart, textarea.selectionEnd) - const undoOrderedListResult = undoOrderedListStyle(selectedText) - const undoUnorderedListResult = undoUnorderedListStyle(undoOrderedListResult.text) + // If the user intent was to do an undo, we will stop after this. + // Otherwise, we will still undo to other list type to prevent list stacking + let undoResult: UndoResult + if (style.orderedList) { + undoResult = undoOrderedListStyle(selectedText) + selectedText = undoUnorderedListStyle(undoResult.text).text + } else { + undoResult = undoUnorderedListStyle(selectedText) + selectedText = undoOrderedListStyle(undoResult.text).text + } - if (undoOrderedListResult.processed || undoUnorderedListResult.processed) { - // if (noInitialSelection) { - // selectionStart = Math.max(selectionStart - prefix.length, 0) - // selectionEnd = selectionStart - // } else { - // selectionStart = Math.max(selectionStart - prefix.length, 0) - // selectionEnd = selectionEnd + prefix.length // * lines.length - // } - return {text: undoUnorderedListResult.text, selectionStart, selectionEnd} + if (undoResult.processed) { + // // if (noInitialSelection) { + // // selectionStart = Math.max(selectionStart - prefix.length, 0) + // // selectionEnd = selectionStart + // // } else { + // // selectionStart = Math.max(selectionStart - prefix.length, 0) + // // selectionEnd = selectionEnd + prefix.length // * lines.length + // // } + return {text: undoResult.text, selectionStart, selectionEnd} } - selectedText = undoUnorderedListResult.text + // selectedText = undoResult.text const lines = selectedText.split('\n').map((value, index) => { return `${prefix(index)}${value}` From dd3e9e76857d772d05583be2762a907d3f091a51 Mon Sep 17 00:00:00 2001 From: Patrick Dinger <121539+paxos@users.noreply.github.com> Date: Tue, 30 Nov 2021 14:10:58 -1000 Subject: [PATCH 12/27] Fix selection after undo --- src/index.ts | 24 +++++++++++------------- 1 file changed, 11 insertions(+), 13 deletions(-) diff --git a/src/index.ts b/src/index.ts index bff0c1b..6a48373 100644 --- a/src/index.ts +++ b/src/index.ts @@ -678,19 +678,6 @@ function listStyle(textarea: HTMLTextAreaElement, style: StyleArgs): SelectionRa selectedText = undoOrderedListStyle(undoResult.text).text } - if (undoResult.processed) { - // // if (noInitialSelection) { - // // selectionStart = Math.max(selectionStart - prefix.length, 0) - // // selectionEnd = selectionStart - // // } else { - // // selectionStart = Math.max(selectionStart - prefix.length, 0) - // // selectionEnd = selectionEnd + prefix.length // * lines.length - // // } - return {text: undoResult.text, selectionStart, selectionEnd} - } - - // selectedText = undoResult.text - const lines = selectedText.split('\n').map((value, index) => { return `${prefix(index)}${value}` }) @@ -699,6 +686,17 @@ function listStyle(textarea: HTMLTextAreaElement, style: StyleArgs): SelectionRa return previousValue + prefix(currentIndex).length }, 0) + if (undoResult.processed) { + if (noInitialSelection) { + selectionStart = Math.max(selectionStart - prefix(0).length, 0) + selectionEnd = selectionStart + } else { + selectionStart = Math.max(selectionStart - prefix.length, 0) + selectionEnd = selectionEnd + totalPrefixLength + } + return {text: undoResult.text, selectionStart, selectionEnd} + } + const {newlinesToAppend, newlinesToPrepend} = newlinesToSurroundSelectedText(textarea) if (noInitialSelection) { From 7f1d9068e53a3af4fbd696e82e070dffe428cfd0 Mon Sep 17 00:00:00 2001 From: Patrick Dinger <121539+paxos@users.noreply.github.com> Date: Tue, 30 Nov 2021 14:14:42 -1000 Subject: [PATCH 13/27] Improve selection handling --- src/index.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/index.ts b/src/index.ts index 6a48373..a5ec6b9 100644 --- a/src/index.ts +++ b/src/index.ts @@ -691,7 +691,7 @@ function listStyle(textarea: HTMLTextAreaElement, style: StyleArgs): SelectionRa selectionStart = Math.max(selectionStart - prefix(0).length, 0) selectionEnd = selectionStart } else { - selectionStart = Math.max(selectionStart - prefix.length, 0) + selectionStart = Math.max(selectionStart - prefix(0).length, 0) selectionEnd = selectionEnd + totalPrefixLength } return {text: undoResult.text, selectionStart, selectionEnd} From 97252707a3e1c9c93af6e2bf4382d013bc0ac64a Mon Sep 17 00:00:00 2001 From: Patrick Dinger <121539+paxos@users.noreply.github.com> Date: Tue, 30 Nov 2021 14:20:56 -1000 Subject: [PATCH 14/27] Fix selection tests --- src/index.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/index.ts b/src/index.ts index a5ec6b9..423d268 100644 --- a/src/index.ts +++ b/src/index.ts @@ -692,7 +692,7 @@ function listStyle(textarea: HTMLTextAreaElement, style: StyleArgs): SelectionRa selectionEnd = selectionStart } else { selectionStart = Math.max(selectionStart - prefix(0).length, 0) - selectionEnd = selectionEnd + totalPrefixLength + selectionEnd = selectionEnd - totalPrefixLength } return {text: undoResult.text, selectionStart, selectionEnd} } From 4b7a29afcc2febfe5f3e80a8839596ac63506825 Mon Sep 17 00:00:00 2001 From: Patrick Dinger <121539+paxos@users.noreply.github.com> Date: Tue, 30 Nov 2021 14:21:01 -1000 Subject: [PATCH 15/27] Adjust stacking test --- test/test.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/test.js b/test/test.js index 410d413..5c973a3 100644 --- a/test/test.js +++ b/test/test.js @@ -619,14 +619,14 @@ describe('markdown-toolbar-element', 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()) + 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()) + assert.equal('One\n\n- Two|\n\nT|hree', visualValue()) }) it('turns line into list when you click the unordered list icon with selection', function () { From a43a40385a9af47b055a8096bf65345a772dea7e Mon Sep 17 00:00:00 2001 From: Patrick Dinger <121539+paxos@users.noreply.github.com> Date: Tue, 30 Nov 2021 14:32:56 -1000 Subject: [PATCH 16/27] Simpliy multiline selections --- src/index.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/index.ts b/src/index.ts index 423d268..c58382d 100644 --- a/src/index.ts +++ b/src/index.ts @@ -703,8 +703,8 @@ function listStyle(textarea: HTMLTextAreaElement, style: StyleArgs): SelectionRa selectionStart = Math.max(selectionStart + prefix(0).length + newlinesToAppend.length, 0) selectionEnd = selectionStart } else { - selectionStart = Math.max(selectionStart + prefix(0).length + newlinesToAppend.length, 0) - selectionEnd = selectionEnd + newlinesToAppend.length + totalPrefixLength + selectionStart = Math.max(textarea.selectionStart + newlinesToAppend.length, 0) + selectionEnd = textarea.selectionEnd + newlinesToAppend.length + totalPrefixLength } const text = newlinesToAppend + lines.join('\n') + newlinesToPrepend From 12e7e56f526f3002ac2e3bd8722602ca7576e56b Mon Sep 17 00:00:00 2001 From: Patrick Dinger <121539+paxos@users.noreply.github.com> Date: Wed, 1 Dec 2021 11:30:33 -1000 Subject: [PATCH 17/27] Fix new tests --- test/test.js | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/test/test.js b/test/test.js index 5c973a3..744ab20 100644 --- a/test/test.js +++ b/test/test.js @@ -512,19 +512,19 @@ describe('markdown-toolbar-element', function () { it('turns line into list if partial line is selected', function () { setVisualValue('One\nT|w|o\nThree\n') clickToolbar('md-ordered-list') - assert.equal('One\n\n1. T|w|o\n\nThree\n', visualValue()) + assert.equal('One\n\n|1. Two|\n\nThree\n', visualValue()) }) it('turns two lines into list if two lines are selected', function () { setVisualValue('|One\nTwo|\nThree\n') clickToolbar('md-ordered-list') - assert.equal('1. |One\n2. Two|\n\nThree\n', visualValue()) + assert.equal('|1. One\n2. Two|\n\nThree\n', visualValue()) }) it('turns two lines into list if 2 lines are partially selected', function () { setVisualValue('O|ne\nTw|o\nThree\n') clickToolbar('md-ordered-list') - assert.equal('1. O|ne\n2. Tw|o\n\nThree\n', visualValue()) + assert.equal('|1. One\n2. Two|\n\nThree\n', visualValue()) }) }) @@ -556,19 +556,19 @@ describe('markdown-toolbar-element', function () { it('turns line into list if partial line is selected', function () { setVisualValue('One\nT|w|o\nThree\n') clickToolbar('md-unordered-list') - assert.equal('One\n\n- T|w|o\n\nThree\n', visualValue()) + assert.equal('One\n\n|- Two|\n\nThree\n', visualValue()) }) it('turns two lines into list if two lines are selected', function () { setVisualValue('|One\nTwo|\nThree\n') clickToolbar('md-unordered-list') - assert.equal('- |One\n- Two|\n\nThree\n', visualValue()) + assert.equal('|- One\n- Two|\n\nThree\n', visualValue()) }) it('turns two lines into list if 2 lines are partially selected', function () { setVisualValue('O|ne\nTw|o\nThree\n') clickToolbar('md-unordered-list') - assert.equal('- O|ne\n- Tw|o\n\nThree\n', visualValue()) + assert.equal('|- One\n- Two|\n\nThree\n', visualValue()) }) it('undo list if cursor at end of line', function () { From f24bffece276c60980967a502652cd27fe0e2707 Mon Sep 17 00:00:00 2001 From: Patrick Dinger <121539+paxos@users.noreply.github.com> Date: Wed, 1 Dec 2021 11:56:05 -1000 Subject: [PATCH 18/27] Adjust tests --- test/test.js | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/test/test.js b/test/test.js index 744ab20..2214b63 100644 --- a/test/test.js +++ b/test/test.js @@ -619,20 +619,20 @@ describe('markdown-toolbar-element', 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()) + 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') + setVisualValue('One\n|Two|\nThree\n') clickToolbar('md-ordered-list') clickToolbar('md-unordered-list') - assert.equal('One\n\n- Two|\n\nT|hree', visualValue()) + assert.equal('One\n\n|- Two|\n\nThree', 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') - assert.equal('One\n\n- |Two|\n\nThree\n', visualValue()) + assert.equal('One\n\n|- Two|\n\nThree\n', visualValue()) }) it('turns line into list when you click the unordered list icon without selection', function () { @@ -648,21 +648,21 @@ describe('markdown-toolbar-element', function () { }) it('prefixes newlines when a list is created on the last line', function () { - setVisualValue("Here's a list:|One|") + setVisualValue("Here's a |list:|") clickToolbar('md-unordered-list') - assert.equal("Here's a list:\n\n- |One|", visualValue()) + assert.equal("|- Here's a list:|", visualValue()) }) it('surrounds list with newlines when a list is created on an existing line', function () { setVisualValue("Here's a list:|One|\nThis is text after the list") clickToolbar('md-unordered-list') - assert.equal("Here's a list:\n\n- |One|\n\nThis is text after the list", visualValue()) + assert.equal("|- Here's a list:One|\n\nThis is text after the list", visualValue()) }) it('undo the list when button is clicked again', function () { setVisualValue('|Two|') clickToolbar('md-unordered-list') - assert.equal('- |Two|', visualValue()) + assert.equal('|- Two|', visualValue()) clickToolbar('md-unordered-list') assert.equal('|Two|', visualValue()) }) @@ -670,7 +670,7 @@ describe('markdown-toolbar-element', function () { it('creates ordered list without selection', function () { setVisualValue('apple\n|pear\nbanana\n') clickToolbar('md-ordered-list') - assert.equal('apple\n\n1. |\n\npear\nbanana\n', visualValue()) + assert.equal('apple\n\n1. |pear\n\nbanana\n', visualValue()) }) it('undo an ordered list without selection', function () { From 5e6300135d0af2bd5f8d6fd2e66248259dca12c1 Mon Sep 17 00:00:00 2001 From: Patrick Dinger <121539+paxos@users.noreply.github.com> Date: Wed, 1 Dec 2021 12:54:19 -1000 Subject: [PATCH 19/27] Fix undo selection behavior --- src/index.ts | 50 +++++++++++++++++++++++++++++++------------------- test/test.js | 12 ++++++------ 2 files changed, 37 insertions(+), 25 deletions(-) diff --git a/src/index.ts b/src/index.ts index c58382d..4ab662e 100644 --- a/src/index.ts +++ b/src/index.ts @@ -648,6 +648,14 @@ function undoUnorderedListStyle(text: string): UndoResult { } } +const prefix = (index: number, unorderedList: boolean): string => { + if (unorderedList) { + return '- ' + } else { + return `${index + 1}. ` + } +} + function listStyle(textarea: HTMLTextAreaElement, style: StyleArgs): SelectionRange { const noInitialSelection = textarea.selectionStart === textarea.selectionEnd let selectionStart = textarea.selectionStart @@ -656,43 +664,42 @@ function listStyle(textarea: HTMLTextAreaElement, style: StyleArgs): SelectionRa // Select whole line expandSelectionToLine(textarea) - const prefix = (index: number): string => { - if (style.unorderedList) { - return '- ' - } else if (style.orderedList) { - return `${index + 1}. ` - } - return '' - } - let selectedText = textarea.value.slice(textarea.selectionStart, textarea.selectionEnd) // If the user intent was to do an undo, we will stop after this. // Otherwise, we will still undo to other list type to prevent list stacking + let undoResultOpositeList: UndoResult let undoResult: UndoResult + if (style.orderedList) { undoResult = undoOrderedListStyle(selectedText) - selectedText = undoUnorderedListStyle(undoResult.text).text + undoResultOpositeList = undoUnorderedListStyle(undoResult.text) + selectedText = undoResultOpositeList.text } else { undoResult = undoUnorderedListStyle(selectedText) - selectedText = undoOrderedListStyle(undoResult.text).text + undoResultOpositeList = undoOrderedListStyle(undoResult.text) + selectedText = undoResultOpositeList.text } const lines = selectedText.split('\n').map((value, index) => { - return `${prefix(index)}${value}` + return `${prefix(index, style.unorderedList)}${value}` }) const totalPrefixLength = lines.reduce((previousValue, currentValue, currentIndex) => { - return previousValue + prefix(currentIndex).length + return previousValue + prefix(currentIndex, style.unorderedList).length + }, 0) + + const totalPrefixLengthOpositeList = lines.reduce((previousValue, currentValue, currentIndex) => { + return previousValue + prefix(currentIndex, !style.unorderedList).length }, 0) if (undoResult.processed) { if (noInitialSelection) { - selectionStart = Math.max(selectionStart - prefix(0).length, 0) + selectionStart = Math.max(selectionStart - prefix(0, style.unorderedList).length, 0) selectionEnd = selectionStart } else { - selectionStart = Math.max(selectionStart - prefix(0).length, 0) - selectionEnd = selectionEnd - totalPrefixLength + selectionStart = textarea.selectionStart + selectionEnd = textarea.selectionEnd - prefix(0, style.unorderedList).length } return {text: undoResult.text, selectionStart, selectionEnd} } @@ -700,11 +707,16 @@ function listStyle(textarea: HTMLTextAreaElement, style: StyleArgs): SelectionRa const {newlinesToAppend, newlinesToPrepend} = newlinesToSurroundSelectedText(textarea) if (noInitialSelection) { - selectionStart = Math.max(selectionStart + prefix(0).length + newlinesToAppend.length, 0) + selectionStart = Math.max(selectionStart + prefix(0, style.unorderedList).length + newlinesToAppend.length, 0) selectionEnd = selectionStart } else { - selectionStart = Math.max(textarea.selectionStart + newlinesToAppend.length, 0) - selectionEnd = textarea.selectionEnd + newlinesToAppend.length + totalPrefixLength + if (undoResultOpositeList.processed) { + selectionStart = Math.max(textarea.selectionStart + newlinesToAppend.length, 0) + selectionEnd = textarea.selectionEnd + newlinesToAppend.length + totalPrefixLength - totalPrefixLengthOpositeList + } else { + selectionStart = Math.max(textarea.selectionStart + newlinesToAppend.length, 0) + selectionEnd = textarea.selectionEnd + newlinesToAppend.length + totalPrefixLength + } } const text = newlinesToAppend + lines.join('\n') + newlinesToPrepend diff --git a/test/test.js b/test/test.js index 2214b63..a155d8f 100644 --- a/test/test.js +++ b/test/test.js @@ -598,19 +598,19 @@ describe('markdown-toolbar-element', function () { it('undo list if partial line is selected', function () { setVisualValue('One\n\n- T|w|o\n\nThree\n') clickToolbar('md-unordered-list') - assert.equal('One\n\nT|w|o\n\nThree\n', visualValue()) + assert.equal('One\n\n|Two|\n\nThree\n', visualValue()) }) it('undo two lines list if two lines are selected', function () { setVisualValue('|- One\n- Two|\n\nThree\n') clickToolbar('md-unordered-list') - assert.equal('|One\nTwo|\n\nThree\n', visualValue()) + assert.equal('|One\nTwo\n\n|Three\n', visualValue()) }) it('undo two lines list if 2 lines are partially selected', function () { setVisualValue('- O|ne\n- Tw|o\n\nThree\n') clickToolbar('md-unordered-list') - assert.equal('O|ne\nTw|o\n\nThree\n', visualValue()) + assert.equal('|One\nTwo\n\n|Three\n', visualValue()) }) }) @@ -619,14 +619,14 @@ describe('markdown-toolbar-element', 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()) + 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\nThree', visualValue()) + assert.equal('One\n\n|- Two|\n\nThree\n', visualValue()) }) it('turns line into list when you click the unordered list icon with selection', function () { @@ -706,7 +706,7 @@ describe('markdown-toolbar-element', function () { it('undo an ordered list by selecting multiple styled lines', function () { setVisualValue('|1. One\n2. Two\n3. Three|\n') clickToolbar('md-ordered-list') - assert.equal('|One\nTwo\nThree|\n', visualValue()) + assert.equal('|One\nTwo\nThree\n|', visualValue()) }) }) From 92e4819457714531342639541efb54ceb2806a9a Mon Sep 17 00:00:00 2001 From: Patrick Dinger <121539+paxos@users.noreply.github.com> Date: Wed, 1 Dec 2021 12:55:48 -1000 Subject: [PATCH 20/27] Remove unused code --- src/index.ts | 63 ---------------------------------------------------- 1 file changed, 63 deletions(-) diff --git a/src/index.ts b/src/index.ts index 4ab662e..1c374ff 100644 --- a/src/index.ts +++ b/src/index.ts @@ -448,17 +448,6 @@ function expandSelectionToLine(textarea: HTMLTextAreaElement) { } } -function selectionIndexForLine(lines: string[], line: number): SelectionRange | null { - let counter = 0 - for (let index = 0; index < lines.length; index++) { - if (index === line) { - return {selectionStart: counter, selectionEnd: counter + lines[index].length, text: ''} - } - counter += lines[index].length + 1 - } - return null -} - function expandSelectedText( textarea: HTMLTextAreaElement, prefixToUse: string, @@ -723,46 +712,6 @@ function listStyle(textarea: HTMLTextAreaElement, style: StyleArgs): SelectionRa return {text, selectionStart, selectionEnd} } -function orderedList(textarea: HTMLTextAreaElement): SelectionRange { - const orderedListRegex = /^\d+\.\s+/ - const noInitialSelection = textarea.selectionStart === textarea.selectionEnd - let selectionEnd - 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/) - startOfLine = textarea.selectionStart - linesBefore[linesBefore.length - 1].length - endOfLine = wordSelectionEnd(textarea.value, textarea.selectionStart, true) - textToUnstyle = textarea.value.slice(startOfLine, endOfLine) - } - const linesToUnstyle = textToUnstyle.split('\n') - const undoStyling = linesToUnstyle.every(line => orderedListRegex.test(line)) - - if (undoStyling) { - lines = linesToUnstyle.map(line => line.replace(orderedListRegex, '')) - text = lines.join('\n') - if (noInitialSelection && startOfLine && endOfLine) { - const lengthDiff = linesToUnstyle[0].length - lines[0].length - selectionStart = selectionEnd = textarea.selectionStart - lengthDiff - textarea.selectionStart = startOfLine - textarea.selectionEnd = endOfLine - } - } else { - lines = numberedLines(lines) - text = lines.join('\n') - const {newlinesToAppend, newlinesToPrepend} = newlinesToSurroundSelectedText(textarea) - selectionStart = textarea.selectionStart + newlinesToAppend.length - selectionEnd = selectionStart + text.length - if (noInitialSelection) selectionStart = selectionEnd - text = newlinesToAppend + text + newlinesToPrepend - } - - return {text, selectionStart, selectionEnd} -} - interface StyleArgs { prefix: string suffix: string @@ -778,18 +727,6 @@ interface StyleArgs { trimFirst: boolean } -function numberedLines(lines: string[]) { - let i - let len - let index - const results = [] - for (index = i = 0, len = lines.length; i < len; index = ++i) { - const line = lines[index] - results.push(`${index + 1}. ${line}`) - } - return results -} - function applyStyle(button: Element, stylesToApply: Style) { const toolbar = button.closest('markdown-toolbar') if (!(toolbar instanceof MarkdownToolbarElement)) return From 65c047c2479283b2569ad12a00d3400d140388a0 Mon Sep 17 00:00:00 2001 From: Patrick Dinger <121539+paxos@users.noreply.github.com> Date: Wed, 1 Dec 2021 12:59:38 -1000 Subject: [PATCH 21/27] Complete test suite for unordered lists --- test/test.js | 42 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 42 insertions(+) diff --git a/test/test.js b/test/test.js index a155d8f..a112ddf 100644 --- a/test/test.js +++ b/test/test.js @@ -526,6 +526,48 @@ describe('markdown-toolbar-element', function () { clickToolbar('md-ordered-list') assert.equal('|1. One\n2. Two|\n\nThree\n', visualValue()) }) + + it('undo list if cursor at end of line', function () { + setVisualValue('One\n\n1. Two|\n\nThree\n') + clickToolbar('md-ordered-list') + assert.equal('One\n\nTwo|\n\nThree\n', visualValue()) + }) + + it('undo list if cursor at end of document', function () { + setVisualValue('One\nTwo\n\n1. Three|') + clickToolbar('md-ordered-list') + assert.equal('One\nTwo\n\nThree|', visualValue()) + }) + + it('undo list if cursor at beginning of line', function () { + setVisualValue('One\n\n1. |Two\n\nThree\n') + clickToolbar('md-ordered-list') + assert.equal('One\n\n|Two\n\nThree\n', visualValue()) + }) + + it('undo list if cursor at middle of line', function () { + setVisualValue('One\n\n1. T|wo\n\nThree\n') + clickToolbar('md-ordered-list') + assert.equal('One\n\nT|wo\n\nThree\n', visualValue()) + }) + + it('undo list if partial line is selected', function () { + setVisualValue('One\n\n1. T|w|o\n\nThree\n') + clickToolbar('md-ordered-list') + assert.equal('One\n\n|Two|\n\nThree\n', visualValue()) + }) + + it('undo two lines list if two lines are selected', function () { + setVisualValue('|1. One\n2. Two|\n\nThree\n') + clickToolbar('md-ordered-list') + assert.equal('|One\nTwo\n\n|Three\n', visualValue()) + }) + + it('undo two lines list if 2 lines are partially selected', function () { + setVisualValue('1. O|ne\n2. Tw|o\n\nThree\n') + clickToolbar('md-ordered-list') + assert.equal('|One\nTwo\n\n|Three\n', visualValue()) + }) }) describe('unordered list', function () { From 95c201e6e7d6baca8c772a2eda01fe19ba4833e1 Mon Sep 17 00:00:00 2001 From: Patrick Dinger <121539+paxos@users.noreply.github.com> Date: Wed, 1 Dec 2021 13:18:33 -1000 Subject: [PATCH 22/27] Fix new tests --- src/index.ts | 2 +- test/test.js | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/index.ts b/src/index.ts index 1c374ff..8dab5fb 100644 --- a/src/index.ts +++ b/src/index.ts @@ -688,7 +688,7 @@ function listStyle(textarea: HTMLTextAreaElement, style: StyleArgs): SelectionRa selectionEnd = selectionStart } else { selectionStart = textarea.selectionStart - selectionEnd = textarea.selectionEnd - prefix(0, style.unorderedList).length + selectionEnd = textarea.selectionEnd - totalPrefixLength } return {text: undoResult.text, selectionStart, selectionEnd} } diff --git a/test/test.js b/test/test.js index a112ddf..c6279c1 100644 --- a/test/test.js +++ b/test/test.js @@ -560,13 +560,13 @@ describe('markdown-toolbar-element', function () { it('undo two lines list if two lines are selected', function () { setVisualValue('|1. One\n2. Two|\n\nThree\n') clickToolbar('md-ordered-list') - assert.equal('|One\nTwo\n\n|Three\n', visualValue()) + assert.equal('|One\nTwo|\n\nThree\n', visualValue()) }) it('undo two lines list if 2 lines are partially selected', function () { setVisualValue('1. O|ne\n2. Tw|o\n\nThree\n') clickToolbar('md-ordered-list') - assert.equal('|One\nTwo\n\n|Three\n', visualValue()) + assert.equal('|One\nTwo|\n\nThree\n', visualValue()) }) }) @@ -646,13 +646,13 @@ describe('markdown-toolbar-element', function () { it('undo two lines list if two lines are selected', function () { setVisualValue('|- One\n- Two|\n\nThree\n') clickToolbar('md-unordered-list') - assert.equal('|One\nTwo\n\n|Three\n', visualValue()) + assert.equal('|One\nTwo|\n\nThree\n', visualValue()) }) it('undo two lines list if 2 lines are partially selected', function () { setVisualValue('- O|ne\n- Tw|o\n\nThree\n') clickToolbar('md-unordered-list') - assert.equal('|One\nTwo\n\n|Three\n', visualValue()) + assert.equal('|One\nTwo|\n\nThree\n', visualValue()) }) }) @@ -748,7 +748,7 @@ describe('markdown-toolbar-element', function () { it('undo an ordered list by selecting multiple styled lines', function () { setVisualValue('|1. One\n2. Two\n3. Three|\n') clickToolbar('md-ordered-list') - assert.equal('|One\nTwo\nThree\n|', visualValue()) + assert.equal('|One\nTwo\nThree|\n', visualValue()) }) }) From 7827c3957e111561500619f573ba81776d42fdfc Mon Sep 17 00:00:00 2001 From: Patrick Dinger <121539+paxos@users.noreply.github.com> Date: Wed, 1 Dec 2021 14:18:03 -1000 Subject: [PATCH 23/27] Make code more consistent --- src/index.ts | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/index.ts b/src/index.ts index 8dab5fb..b409161 100644 --- a/src/index.ts +++ b/src/index.ts @@ -637,7 +637,7 @@ function undoUnorderedListStyle(text: string): UndoResult { } } -const prefix = (index: number, unorderedList: boolean): string => { +function makePrefix(index: number, unorderedList: boolean): string { if (unorderedList) { return '- ' } else { @@ -671,20 +671,20 @@ function listStyle(textarea: HTMLTextAreaElement, style: StyleArgs): SelectionRa } const lines = selectedText.split('\n').map((value, index) => { - return `${prefix(index, style.unorderedList)}${value}` + return `${makePrefix(index, style.unorderedList)}${value}` }) const totalPrefixLength = lines.reduce((previousValue, currentValue, currentIndex) => { - return previousValue + prefix(currentIndex, style.unorderedList).length + return previousValue + makePrefix(currentIndex, style.unorderedList).length }, 0) const totalPrefixLengthOpositeList = lines.reduce((previousValue, currentValue, currentIndex) => { - return previousValue + prefix(currentIndex, !style.unorderedList).length + return previousValue + makePrefix(currentIndex, !style.unorderedList).length }, 0) if (undoResult.processed) { if (noInitialSelection) { - selectionStart = Math.max(selectionStart - prefix(0, style.unorderedList).length, 0) + selectionStart = Math.max(selectionStart - makePrefix(0, style.unorderedList).length, 0) selectionEnd = selectionStart } else { selectionStart = textarea.selectionStart @@ -696,7 +696,7 @@ function listStyle(textarea: HTMLTextAreaElement, style: StyleArgs): SelectionRa const {newlinesToAppend, newlinesToPrepend} = newlinesToSurroundSelectedText(textarea) if (noInitialSelection) { - selectionStart = Math.max(selectionStart + prefix(0, style.unorderedList).length + newlinesToAppend.length, 0) + selectionStart = Math.max(selectionStart + makePrefix(0, style.unorderedList).length + newlinesToAppend.length, 0) selectionEnd = selectionStart } else { if (undoResultOpositeList.processed) { From 242cb0d04e3c8f1faf795e1d68883f1685c07248 Mon Sep 17 00:00:00 2001 From: Patrick Dinger <121539+paxos@users.noreply.github.com> Date: Thu, 2 Dec 2021 10:54:17 -1000 Subject: [PATCH 24/27] Update index.ts Improve code readability Co-Authored-By: Chris Westra --- src/index.ts | 41 +++++++++++++++++++++++------------------ 1 file changed, 23 insertions(+), 18 deletions(-) diff --git a/src/index.ts b/src/index.ts index b409161..feb47c5 100644 --- a/src/index.ts +++ b/src/index.ts @@ -645,6 +645,22 @@ function makePrefix(index: number, unorderedList: boolean): string { } } +function clearExistingListStyle(style: StyleArgs, selectedText: string): [UndoResult, UndoResult, string] { + let undoResultOpositeList: UndoResult + let undoResult: UndoResult + let pristineText + if (style.orderedList) { + undoResult = undoOrderedListStyle(selectedText) + undoResultOpositeList = undoUnorderedListStyle(undoResult.text) + pristineText = undoResultOpositeList.text + } else { + undoResult = undoUnorderedListStyle(selectedText) + undoResultOpositeList = undoOrderedListStyle(undoResult.text) + pristineText = undoResultOpositeList.text + } + return [undoResult, undoResultOpositeList, pristineText] +} + function listStyle(textarea: HTMLTextAreaElement, style: StyleArgs): SelectionRange { const noInitialSelection = textarea.selectionStart === textarea.selectionEnd let selectionStart = textarea.selectionStart @@ -653,32 +669,21 @@ function listStyle(textarea: HTMLTextAreaElement, style: StyleArgs): SelectionRa // Select whole line expandSelectionToLine(textarea) - let selectedText = textarea.value.slice(textarea.selectionStart, textarea.selectionEnd) + const selectedText = textarea.value.slice(textarea.selectionStart, textarea.selectionEnd) // If the user intent was to do an undo, we will stop after this. // Otherwise, we will still undo to other list type to prevent list stacking - let undoResultOpositeList: UndoResult - let undoResult: UndoResult - - if (style.orderedList) { - undoResult = undoOrderedListStyle(selectedText) - undoResultOpositeList = undoUnorderedListStyle(undoResult.text) - selectedText = undoResultOpositeList.text - } else { - undoResult = undoUnorderedListStyle(selectedText) - undoResultOpositeList = undoOrderedListStyle(undoResult.text) - selectedText = undoResultOpositeList.text - } + const [undoResult, undoResultOpositeList, pristineText] = clearExistingListStyle(style, selectedText) - const lines = selectedText.split('\n').map((value, index) => { + const prefixedLines = pristineText.split('\n').map((value, index) => { return `${makePrefix(index, style.unorderedList)}${value}` }) - const totalPrefixLength = lines.reduce((previousValue, currentValue, currentIndex) => { + const totalPrefixLength = prefixedLines.reduce((previousValue, _currentValue, currentIndex) => { return previousValue + makePrefix(currentIndex, style.unorderedList).length }, 0) - const totalPrefixLengthOpositeList = lines.reduce((previousValue, currentValue, currentIndex) => { + const totalPrefixLengthOpositeList = prefixedLines.reduce((previousValue, _currentValue, currentIndex) => { return previousValue + makePrefix(currentIndex, !style.unorderedList).length }, 0) @@ -690,10 +695,11 @@ function listStyle(textarea: HTMLTextAreaElement, style: StyleArgs): SelectionRa selectionStart = textarea.selectionStart selectionEnd = textarea.selectionEnd - totalPrefixLength } - return {text: undoResult.text, selectionStart, selectionEnd} + return {text: pristineText, selectionStart, selectionEnd} } const {newlinesToAppend, newlinesToPrepend} = newlinesToSurroundSelectedText(textarea) + const text = newlinesToAppend + prefixedLines.join('\n') + newlinesToPrepend if (noInitialSelection) { selectionStart = Math.max(selectionStart + makePrefix(0, style.unorderedList).length + newlinesToAppend.length, 0) @@ -708,7 +714,6 @@ function listStyle(textarea: HTMLTextAreaElement, style: StyleArgs): SelectionRa } } - const text = newlinesToAppend + lines.join('\n') + newlinesToPrepend return {text, selectionStart, selectionEnd} } From 979f51c6218f67d092190a24aeef72c3627a42ca Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kristj=C3=A1n=20Oddsson?= Date: Fri, 3 Dec 2021 11:16:40 +0000 Subject: [PATCH 25/27] Run test workflow on pull requests --- .github/workflows/nodejs.yml | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/.github/workflows/nodejs.yml b/.github/workflows/nodejs.yml index 7f3b8c8..96f8d37 100644 --- a/.github/workflows/nodejs.yml +++ b/.github/workflows/nodejs.yml @@ -1,6 +1,10 @@ name: Node CI -on: push +on: + pull_request: + push: + branches: + - main jobs: build: runs-on: ubuntu-latest From d36259a9ddba830a4cab9fc977fc92a591c42007 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kristj=C3=A1n=20Oddsson?= Date: Fri, 3 Dec 2021 11:18:40 +0000 Subject: [PATCH 26/27] Allow test workflow to be triggered manually --- .github/workflows/nodejs.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/nodejs.yml b/.github/workflows/nodejs.yml index 96f8d37..c01748a 100644 --- a/.github/workflows/nodejs.yml +++ b/.github/workflows/nodejs.yml @@ -1,6 +1,7 @@ name: Node CI on: + workflow_dispatch: pull_request: push: branches: From b75619d4291fc843464655158a31f6aec4b611f1 Mon Sep 17 00:00:00 2001 From: Simon Taranto Date: Mon, 6 Dec 2021 12:26:16 -0700 Subject: [PATCH 27/27] 2.1.0 --- package-lock.json | 2 +- package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/package-lock.json b/package-lock.json index d566780..0c925f7 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "@github/markdown-toolbar-element", - "version": "2.0.0", + "version": "2.1.0", "lockfileVersion": 2, "requires": true, "packages": { diff --git a/package.json b/package.json index 898188d..ccdeb30 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@github/markdown-toolbar-element", - "version": "2.0.0", + "version": "2.1.0", "description": "Markdown formatting buttons for text inputs.", "repository": "github/markdown-toolbar-element", "type": "module",