mirror of
https://github.com/go-gitea/gitea.git
synced 2026-11-12 16:43:29 +00:00
Backport #40334 by @SudhanshuMatrix Markdown renders `[X]` as a checked task like `[x]`, but parts of the frontend only recognize lowercase `x`. - Clicking a `[X]` checkbox now unchecks it instead of failing. - Pressing Enter on a `- [X]` line in the editor continues the list with `- [ ] ` instead of dropping the checkbox. Assisted-by: Claude Code:claude-opus-5-5 Co-authored-by: Shudhanshu Singh <sudhanshuwriterblc@gmail.com> Co-authored-by: silverwind <me@silverwind.io>
This commit is contained in:
4 files changed
+8
-7
No files matched your search
@@ -199,5 +199,5 @@ test('EditorMarkdown', () => {
|
||||
testInput('- [ ]', '- [ ]\n- ');
|
||||
testInput('- [ ] foo', '- [ ] foo\n- [ ] ');
|
||||
testInput('* [x] foo', '* [x] foo\n* [ ] ');
|
||||
testInput('1. [x] foo', '1. [x] foo\n2. [ ] ');
|
||||
testInput('1. [X] foo', '1. [X] foo\n2. [ ] ');
|
||||
});
|
||||
@@ -148,9 +148,9 @@ export function markdownHandleIndention(tvs: TextareaValueSelection): MarkdownHa
|
||||
lineContent = lineContent.slice(indention.length);
|
||||
if (linesBuf.inlinePos <= indention.length) return unhandled; // if cursor is at the indention, do nothing, let the browser handle it
|
||||
|
||||
// parse the prefixes: "1. ", "- ", "* ", there could also be " [ ] " or " [x] " for task lists
|
||||
// parse the prefixes: "1. ", "- ", "* ", there could also be " [ ] ", " [x] " 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]+\.|[-*])(\s\[([ x])\])?\s/.exec(lineContent);
|
||||
const prefixMatch = /^([0-9]+\.|[-*])(\s\[([ xX])\])?\s/.exec(lineContent);
|
||||
let prefix = '';
|
||||
if (prefixMatch) {
|
||||
prefix = prefixMatch[0];
|
||||
@@ -168,7 +168,7 @@ export function markdownHandleIndention(tvs: TextareaValueSelection): MarkdownHa
|
||||
// start a new line with the same indention
|
||||
let newPrefix = prefix;
|
||||
if (/^\d+\./.test(prefix)) newPrefix = `1. ${newPrefix.slice(newPrefix.indexOf('.') + 2)}`;
|
||||
newPrefix = newPrefix.replace('[x]', '[ ]');
|
||||
newPrefix = newPrefix.replace(/\[[xX]\]/, '[ ]');
|
||||
|
||||
const inlinePos = linesBuf.inlinePos;
|
||||
linesBuf.lines[linesBuf.posLineIndex] = line.substring(0, inlinePos);
|
||||
|
||||
@@ -3,6 +3,7 @@ import {toggleTasklistCheckbox} from './tasklist.ts';
|
||||
test('toggleTasklistCheckbox', () => {
|
||||
expect(toggleTasklistCheckbox('- [ ] task', 3, true)).toEqual('- [x] task');
|
||||
expect(toggleTasklistCheckbox('- [x] task', 3, false)).toEqual('- [ ] task');
|
||||
expect(toggleTasklistCheckbox('- [X] task', 3, false)).toEqual('- [ ] task');
|
||||
expect(toggleTasklistCheckbox('- [ ] task', 0, true)).toBeNull();
|
||||
expect(toggleTasklistCheckbox('- [ ] task', 99, true)).toBeNull();
|
||||
expect(toggleTasklistCheckbox('😀 - [ ] task', 8, true)).toEqual('😀 - [x] task');
|
||||
|
||||
@@ -5,14 +5,14 @@ const preventListener = (e: Event) => e.preventDefault();
|
||||
|
||||
/**
|
||||
* Toggle a task list checkbox in markdown content.
|
||||
* `position` is the byte offset of the space or `x` character inside `[ ]`.
|
||||
* `position` is the byte offset of the space, `x` or `X` character inside `[ ]`.
|
||||
* Returns the updated content, or null if the position is invalid.
|
||||
*/
|
||||
export function toggleTasklistCheckbox(content: string, position: number, checked: boolean): string | null {
|
||||
const buffer = new TextEncoder().encode(content);
|
||||
// Indexes may fall off the ends and return undefined.
|
||||
if (buffer[position - 1] !== '['.charCodeAt(0) ||
|
||||
buffer[position] !== ' '.charCodeAt(0) && buffer[position] !== 'x'.charCodeAt(0) ||
|
||||
!' xX'.includes(String.fromCharCode(buffer[position])) ||
|
||||
buffer[position + 1] !== ']'.charCodeAt(0)) {
|
||||
return null;
|
||||
}
|
||||
@@ -49,7 +49,7 @@ export function initMarkupTasklist(elMarkup: HTMLElement): void {
|
||||
if (newContent === null) {
|
||||
// Position is probably wrong. Revert and don't allow change.
|
||||
checkbox.checked = !checkbox.checked;
|
||||
throw new Error(`Expected position to be space or x and surrounded by brackets, but it's not: position=${position}`);
|
||||
throw new Error(`Expected position to be space, x or X and surrounded by brackets, but it's not: position=${position}`);
|
||||
}
|
||||
|
||||
if (newContent === oldContent) {
|
||||
|
||||
Reference in new issue
Block a user