Fix task list checkboxes for numbered lists (#1233)

* Fix replacer regex

This regex handles the replacement of the [ ] with [x] and reverse.
Until now it was build to check for an unordered list beginning with "*" or "-".
This change permits "+" as well as digits followed by a dot (ordered lists).

Signed-off-by: Erik Michelson <github@erik.michelson.eu>

* Add cypress tests for task lists

Signed-off-by: Erik Michelson <github@erik.michelson.eu>

* Add bracket syntax for numbered lists

Signed-off-by: Erik Michelson <github@erik.michelson.eu>
This commit is contained in:
Erik Michelson 2021-05-04 20:34:16 +02:00 committed by GitHub
parent eac288cebc
commit 726b084509
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 88 additions and 1 deletions

View file

@ -0,0 +1,87 @@
/*
* SPDX-FileCopyrightText: 2021 The HedgeDoc developers (see AUTHORS file)
*
* SPDX-License-Identifier: AGPL-3.0-only
*/
const TEST_STRING_UNCHECKED = '- [ ] abc\n\n* [ ] abc\n\n+ [ ] abc\n\n1. [ ] abc\n\n10. [ ] abc\n\n5) [ ] abc'
const TEST_STRING_CHECKED_LOWER = '- [x] abc\n\n* [x] abc\n\n+ [x] abc\n\n1. [x] abc\n\n10. [x] abc\n\n5) [x] abc'
const TEST_STRING_CHECKED_UPPER = '- [X] abc\n\n* [X] abc\n\n+ [X] abc\n\n1. [X] abc\n\n10. [X] abc\n\n5) [X] abc'
const TEST_STRING_INVALID = '- [Y] abc\n\n* [ ] abc\n\n+ [-] abc\n\n1. [.] abc\n\n10. [] abc\n\n5) [-] abc'
describe('Task lists ', () => {
beforeEach(() => {
cy.visitTestEditor()
})
describe('render with checkboxes ', () => {
it('when unchecked', () => {
cy.codemirrorFill(TEST_STRING_UNCHECKED)
cy.getMarkdownBody()
.find('input[type=checkbox]')
.should('have.length', 6)
})
it('when checked lowercase', () => {
cy.codemirrorFill(TEST_STRING_CHECKED_LOWER)
cy.getMarkdownBody()
.find('input[type=checkbox]')
.should('have.length', 6)
})
it('when checked uppercase', () => {
cy.codemirrorFill(TEST_STRING_CHECKED_UPPER)
cy.getMarkdownBody()
.find('input[type=checkbox]')
.should('have.length', 6)
})
})
it('do not render as checkboxes when invalid', () => {
cy.codemirrorFill(TEST_STRING_INVALID)
cy.getMarkdownBody()
.find('input[type=checkbox]')
.should('have.length', 0)
})
describe('are clickable and change the markdown source ', () => {
it('from unchecked to checked', () => {
cy.codemirrorFill(TEST_STRING_UNCHECKED)
cy.getMarkdownBody()
.find('input[type=checkbox]')
.each(box => {
box.trigger('click')
})
cy.get('.CodeMirror-line > span')
.should('exist')
.should('contain.text', '[x]')
.should('not.contain.text', '[ ]')
})
it('from checked (lowercase) to unchecked', () => {
cy.codemirrorFill(TEST_STRING_CHECKED_LOWER)
cy.getMarkdownBody()
.find('input[type=checkbox]')
.each(box => {
box.trigger('click')
})
cy.get('.CodeMirror-line > span')
.should('exist')
.should('contain.text', '[ ]')
.should('not.contain.text', '[x]')
})
it('from checked (uppercase) to unchecked', () => {
cy.codemirrorFill(TEST_STRING_CHECKED_UPPER)
cy.getMarkdownBody()
.find('input[type=checkbox]')
.each(box => {
box.trigger('click')
})
cy.get('.CodeMirror-line > span')
.should('exist')
.should('contain.text', '[ ]')
.should('not.contain.text', '[X]')
})
})
})

View file

@ -87,7 +87,7 @@ export const NoteDetailsReducer: Reducer<NoteDetails, NoteDetailsAction> = (stat
}
}
const TASK_REGEX = /(\s*[-*] )(\[[ xX]])( .*)/
const TASK_REGEX = /(\s*(?:[-*+]|\d+[.)]) )(\[[ xX]])( .*)/
const setCheckboxInMarkdownContent = (markdownContent: string, lineInMarkdown: number, checked: boolean): string => {
const lines = markdownContent.split('\n')
const results = TASK_REGEX.exec(lines[lineInMarkdown])