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", pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy