-
-
Notifications
You must be signed in to change notification settings - Fork 5.8k
Add some handy markdown editor features #32400
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 1 commit
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
import {initTextareaMarkdown} from './EditorMarkdown.ts'; | ||
|
||
test('EditorMarkdown', () => { | ||
const textarea = document.createElement('textarea'); | ||
initTextareaMarkdown(textarea); | ||
|
||
const testInput = function (value, expected) { | ||
wxiaoguang marked this conversation as resolved.
Show resolved
Hide resolved
|
||
textarea.value = value; | ||
textarea.setSelectionRange(value.length, value.length); | ||
const e = new KeyboardEvent('keydown', {key: 'Enter', cancelable: true}); | ||
textarea.dispatchEvent(e); | ||
if (!e.defaultPrevented) textarea.value += '\n'; | ||
expect(textarea.value).toEqual(expected); | ||
}; | ||
|
||
testInput('-', '-\n'); | ||
testInput('1.', '1.\n'); | ||
|
||
testInput('- ', ''); | ||
testInput('1. ', ''); | ||
|
||
testInput('- x', '- x\n- '); | ||
testInput('- [ ]', '- [ ]\n- '); | ||
testInput('- [ ] foo', '- [ ] foo\n- [ ] '); | ||
testInput('* [x] foo', '* [x] foo\n* [ ] '); | ||
testInput('1. [x] foo', '1. [x] foo\n1. [ ] '); | ||
}); |
Original file line number | Diff line number | Diff line change | ||
---|---|---|---|---|
|
@@ -4,6 +4,16 @@ export function triggerEditorContentChanged(target) { | |||
target.dispatchEvent(new CustomEvent(EventEditorContentChanged, {bubbles: true})); | ||||
} | ||||
|
||||
export function textareaInsertText(textarea, value) { | ||||
const startPos = textarea.selectionStart; | ||||
const endPos = textarea.selectionEnd; | ||||
textarea.value = textarea.value.substring(0, startPos) + value + textarea.value.substring(endPos); | ||||
textarea.selectionStart = startPos; | ||||
textarea.selectionEnd = startPos + value.length; | ||||
textarea.focus(); | ||||
triggerEditorContentChanged(textarea); | ||||
} | ||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Can it use Line 277 in ec2d159
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. No, it can't at the moment. I know the existence of replaceTextareaSelection but it needs some extra work to merge these two. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The only difference seems to be that this function re-selects the inserted text and focuses the textarea. The re-selection could be pictured in a option and the focus could be done after the function call.
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
No. I do not think making more changes is in this PR's scope since it has been fully tested. And this There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'd prefer if this at least does not break the textarea history. Does CTRL-Z work after inserting content? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This textareaInsertText is not a new function, it is just extracted from insertPlaceholder, nothing worse. There is always a chance to propose new improvements. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Should fix it later. |
||||
|
||||
function handleIndentSelection(textarea, e) { | ||||
const selStart = textarea.selectionStart; | ||||
const selEnd = textarea.selectionEnd; | ||||
|
@@ -46,7 +56,7 @@ function handleIndentSelection(textarea, e) { | |||
triggerEditorContentChanged(textarea); | ||||
} | ||||
|
||||
function handleNewline(textarea, e) { | ||||
function handleNewline(textarea: HTMLTextAreaElement, e: Event) { | ||||
const selStart = textarea.selectionStart; | ||||
const selEnd = textarea.selectionEnd; | ||||
if (selEnd !== selStart) return; // do not process when there is a selection | ||||
|
@@ -66,9 +76,9 @@ function handleNewline(textarea, e) { | |||
const indention = /^\s*/.exec(line)[0]; | ||||
line = line.slice(indention.length); | ||||
|
||||
// parse the prefixes: "1. ", "- ", "* ", "[ ] ", "[x] " | ||||
// parse the prefixes: "1. ", "- ", "* ", there could also be " [ ] " or " [x] " for task lists | ||||
// there must be a space after the prefix because none of "1.foo" / "-foo" is a list item | ||||
const prefixMatch = /^([0-9]+\.|[-*]|\[ \]|\[x\])\s/.exec(line); | ||||
const prefixMatch = /^([0-9]+\.|[-*])(\s\[([ x])\])?\s/.exec(line); | ||||
let prefix = ''; | ||||
if (prefixMatch) { | ||||
prefix = prefixMatch[0]; | ||||
|
@@ -85,8 +95,9 @@ function handleNewline(textarea, e) { | |||
} else { | ||||
// start a new line with the same indention and prefix | ||||
let newPrefix = prefix; | ||||
if (newPrefix === '[x]') newPrefix = '[ ]'; | ||||
if (/^\d+\./.test(newPrefix)) newPrefix = `1. `; // a simple approach, otherwise it needs to parse the lines after the current line | ||||
// a simple approach, otherwise it needs to parse the lines after the current line | ||||
if (/^\d+\./.test(prefix)) newPrefix = `1. ${newPrefix.slice(newPrefix.indexOf('.') + 2)}`; | ||||
newPrefix = newPrefix.replace('[x]', '[ ]'); | ||||
const newLine = `\n${indention}${newPrefix}`; | ||||
textarea.value = value.slice(0, selStart) + newLine + value.slice(selEnd); | ||||
textarea.setSelectionRange(selStart + newLine.length, selStart + newLine.length); | ||||
|
Uh oh!
There was an error while loading. Please reload this page.