Skip to content

Commit ec5f52a

Browse files
committed
Add new behavior for no selection
1 parent 6fd186c commit ec5f52a

File tree

2 files changed

+104
-3
lines changed

2 files changed

+104
-3
lines changed

src/index.ts

Lines changed: 90 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,7 @@ type Style = {
7979
replaceNext?: string
8080
scanFor?: string
8181
orderedList?: boolean
82+
unorderedList?: boolean
8283
prefixSpace?: boolean
8384
}
8485

@@ -205,7 +206,7 @@ if (!window.customElements.get('md-image')) {
205206
class MarkdownUnorderedListButtonElement extends MarkdownButtonElement {
206207
constructor() {
207208
super()
208-
styles.set(this, {prefix: '- ', multiline: true, surroundWithNewlines: true})
209+
styles.set(this, {prefix: '- ', multiline: true, unorderedList: true})
209210
}
210211
}
211212

@@ -421,8 +422,8 @@ function styleSelectedText(textarea: HTMLTextAreaElement, styleArgs: StyleArgs)
421422
const text = textarea.value.slice(textarea.selectionStart, textarea.selectionEnd)
422423

423424
let result
424-
if (styleArgs.orderedList) {
425-
result = orderedList(textarea)
425+
if (styleArgs.orderedList || styleArgs.unorderedList) {
426+
result = listStyle(textarea, styleArgs)
426427
} else if (styleArgs.multiline && isMultipleLines(text)) {
427428
result = multilineStyle(textarea, styleArgs)
428429
} else {
@@ -432,6 +433,17 @@ function styleSelectedText(textarea: HTMLTextAreaElement, styleArgs: StyleArgs)
432433
insertText(textarea, result)
433434
}
434435

436+
export function selectionIndexForLine(lines: string[], line: number): SelectionRange | null {
437+
let counter = 0
438+
for (let index = 0; index < lines.length; index++) {
439+
if (index === line) {
440+
return {selectionStart: counter, selectionEnd: counter + lines[index].length, text: ''}
441+
}
442+
counter += lines[index].length + 1
443+
}
444+
return null
445+
}
446+
435447
function expandSelectedText(
436448
textarea: HTMLTextAreaElement,
437449
prefixToUse: string,
@@ -587,6 +599,79 @@ function multilineStyle(textarea: HTMLTextAreaElement, arg: StyleArgs) {
587599
return {text, selectionStart, selectionEnd}
588600
}
589601

602+
function undoOrderedListStyle(textarea: HTMLTextAreaElement): string[] {
603+
const text = textarea.value.slice(textarea.selectionStart, textarea.selectionEnd)
604+
const lines = text.split('\n')
605+
const orderedListRegex = /^\d+\.\s+/
606+
const result = lines
607+
const shouldUndoOrderedList = lines.every(line => orderedListRegex.test(line))
608+
if (shouldUndoOrderedList) {
609+
return lines.map(line => line.replace(orderedListRegex, ''))
610+
}
611+
return result
612+
}
613+
614+
function undoUnorderedListStyle(textarea: HTMLTextAreaElement): string[] {
615+
const text = textarea.value.slice(textarea.selectionStart, textarea.selectionEnd)
616+
const lines = text.split('\n')
617+
const unorderedListPrefix = '- '
618+
const shouldUndoUnorderedList = lines.every(line => line.startsWith(unorderedListPrefix))
619+
const result = lines
620+
if (shouldUndoUnorderedList) {
621+
return lines.map(line => line.slice(unorderedListPrefix.length, line.length))
622+
}
623+
return result
624+
}
625+
626+
function listStyle(textarea: HTMLTextAreaElement, style: StyleArgs): SelectionRange {
627+
const noInitialSelection = textarea.selectionStart === textarea.selectionEnd
628+
let selectionStart = textarea.selectionStart
629+
let selectionEnd = textarea.selectionEnd
630+
let lines: string[] = []
631+
let text = textarea.value.slice(textarea.selectionStart, textarea.selectionEnd)
632+
let startOfLine, endOfLine
633+
634+
undoOrderedListStyle(textarea)
635+
undoUnorderedListStyle(textarea)
636+
637+
const prefix = '- '
638+
639+
//let selectedText = expandSelectedText(textarea, prefix, '', style.multiline)
640+
641+
// Style only the selected line
642+
if (noInitialSelection) {
643+
const linesBefore = textarea.value.slice(0, textarea.selectionStart).split(/\n/)
644+
lines = textarea.value.split('\n')
645+
646+
const currentLine = linesBefore.length - 1
647+
const currentLineText = lines[currentLine]
648+
649+
// Select whole line
650+
const range = selectionIndexForLine(lines, currentLine)
651+
if (range) {
652+
textarea.selectionStart = range.selectionStart ?? 0
653+
textarea.selectionEnd = range.selectionEnd ?? 0
654+
}
655+
656+
// line with caret
657+
//lines[linesBefore.length - 1] = prefix + linesBefore[linesBefore.length - 1]
658+
659+
text = prefix + currentLineText
660+
661+
// if (style.surroundWithNewlines) {
662+
const {newlinesToAppend, newlinesToPrepend} = newlinesToSurroundSelectedText(textarea)
663+
selectionStart = selectionStart + prefix.length + 1
664+
selectionEnd = selectionStart
665+
text = newlinesToAppend + text + newlinesToPrepend
666+
667+
return {text, selectionStart, selectionEnd}
668+
}
669+
670+
text = lines.join('\n')
671+
672+
return {text, selectionStart, selectionEnd}
673+
}
674+
590675
function orderedList(textarea: HTMLTextAreaElement): SelectionRange {
591676
const orderedListRegex = /^\d+\.\s+/
592677
const noInitialSelection = textarea.selectionStart === textarea.selectionEnd
@@ -638,6 +723,7 @@ interface StyleArgs {
638723
scanFor: string
639724
surroundWithNewlines: boolean
640725
orderedList: boolean
726+
unorderedList: boolean
641727
trimFirst: boolean
642728
}
643729

@@ -668,6 +754,7 @@ function applyStyle(button: Element, stylesToApply: Style) {
668754
scanFor: '',
669755
surroundWithNewlines: false,
670756
orderedList: false,
757+
unorderedList: false,
671758
trimFirst: false
672759
}
673760

test/test.js

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -571,6 +571,20 @@ describe('markdown-toolbar-element', function () {
571571
})
572572

573573
describe('lists', function () {
574+
it('does not stack list styles when selecting multiple lines', function () {
575+
setVisualValue('One\n|Two\nThree|\n')
576+
clickToolbar('md-ordered-list')
577+
clickToolbar('md-unordered-list')
578+
assert.equal('One\n\n|- Two\n- Three|\n', visualValue())
579+
})
580+
581+
it('does not stack list styles when selecting one line', function () {
582+
setVisualValue('One\n|Two|\nThree|\n')
583+
clickToolbar('md-ordered-list')
584+
clickToolbar('md-unordered-list')
585+
assert.equal('One\n\n|- Two\n- Three|\n', visualValue())
586+
})
587+
574588
it('turns line into list when you click the unordered list icon with selection', function () {
575589
setVisualValue('One\n|Two|\nThree\n')
576590
clickToolbar('md-unordered-list')

0 commit comments

Comments
 (0)