Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/nextcloud/text.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorFerdinand Thiessen <rpm@fthiessen.de>2022-07-15 12:05:27 +0300
committerFerdinand Thiessen <rpm@fthiessen.de>2022-07-15 13:34:00 +0300
commit613b6898c066c7a84c7e0aebfe5a399d13ce1d9e (patch)
treee14eb2ed63ecb18fe3bd629addb5c8bc712710c6 /src
parent1b7d876711be312a5230cb4e970eb086c71700fb (diff)
Fix parsing of whitespace used in task lists
Switch to @hedgedoc/markdown-it-task-lists to fix parsing of task lists, namely allowing any whitespace inside the brackets, as by the github markdown specs. Doing this as markdown-it-task-lists seems orphaned, while hedgedoc is maintained and the bug is fixed there. This required adjusting the task-list testcase as the output is slightly different. Signed-off-by: Ferdinand Thiessen <rpm@fthiessen.de>
Diffstat (limited to 'src')
-rw-r--r--src/markdownit/index.js2
-rw-r--r--src/markdownit/splitMixedLists.js16
-rw-r--r--src/nodes/TaskItem.js2
-rw-r--r--src/tests/markdown.spec.js17
-rw-r--r--src/tests/markdownit.spec.js4
5 files changed, 28 insertions, 13 deletions
diff --git a/src/markdownit/index.js b/src/markdownit/index.js
index ca166dbad..e13d1a3aa 100644
--- a/src/markdownit/index.js
+++ b/src/markdownit/index.js
@@ -1,5 +1,5 @@
import MarkdownIt from 'markdown-it'
-import taskLists from 'markdown-it-task-lists'
+import taskLists from '@hedgedoc/markdown-it-task-lists'
import underline from './underline.js'
import splitMixedLists from './splitMixedLists.js'
import callouts from './callouts.js'
diff --git a/src/markdownit/splitMixedLists.js b/src/markdownit/splitMixedLists.js
index cb709af33..5f35e6c1d 100644
--- a/src/markdownit/splitMixedLists.js
+++ b/src/markdownit/splitMixedLists.js
@@ -24,16 +24,16 @@
* @param {object} md Markdown object
*/
export default function splitMixedLists(md) {
- md.core.ruler.after('github-task-lists', 'split-mixed-task-lists', state => {
+ md.core.ruler.after('task-lists', 'split-mixed-task-lists', state => {
const tokens = state.tokens
for (let i = 0; i < tokens.length; i++) {
const token = tokens[i]
- if (token.attrGet('class') !== 'contains-task-list') {
+ if (!includesClass(token, 'contains-task-list')) {
continue
}
const firstChild = tokens[i + 1]
- const startsWithTask = firstChild.attrGet('class') === 'task-list-item'
+ const startsWithTask = includesClass(firstChild, 'task-list-item')
if (!startsWithTask) {
token.attrs.splice(token.attrIndex('class'))
if (token.attrs.length === 0) {
@@ -42,7 +42,7 @@ export default function splitMixedLists(md) {
}
const splitBefore = findChildOf(tokens, i, child => {
return child.nesting === 1
- && child.attrGet('class') !== firstChild.attrGet('class')
+ && includesClass(child, 'task-list-item') !== startsWithTask
})
if (splitBefore > i) {
splitListAt(tokens, splitBefore, state.Token)
@@ -54,6 +54,14 @@ export default function splitMixedLists(md) {
}
/**
+ * @param {object} token MarkdownIT token
+ * @param {string} cls Class name to query
+ */
+function includesClass(token, cls) {
+ return token.attrGet('class')?.split(' ').includes(cls) || false
+}
+
+/**
* @param {Array} tokens - all the tokens in the doc
* @param {number} index - index into the tokens array where to split
* @param {object} TokenConstructor - constructor provided by Markdown-it
diff --git a/src/nodes/TaskItem.js b/src/nodes/TaskItem.js
index 74db3e82a..b602e9130 100644
--- a/src/nodes/TaskItem.js
+++ b/src/nodes/TaskItem.js
@@ -91,7 +91,7 @@ const TaskItem = TipTapTaskItem.extend({
return [
...this.parent(),
wrappingInputRule({
- find: /^\s*([-+*])\s(\[(x|X| ?)\])\s$/,
+ find: /^\s*([-+*])\s(\[(x|X|\s?)\])\s$/,
type: this.type,
getAttributes: match => ({
checked: 'xX'.includes(match[match.length - 1]),
diff --git a/src/tests/markdown.spec.js b/src/tests/markdown.spec.js
index 0f6cbaeed..a682111a3 100644
--- a/src/tests/markdown.spec.js
+++ b/src/tests/markdown.spec.js
@@ -96,10 +96,15 @@ describe('Markdown though editor', () => {
expect(markdownThroughEditor('```\n<?php echo "Hello World";\n```')).toBe('```\n<?php echo "Hello World";\n```')
})
test('checkboxes', () => {
- expect(markdownThroughEditor('- [ ] [asd](sdf)')).toBe('* [ ] [asd](sdf)')
- expect(markdownThroughEditor('- [x] [asd](sdf)')).toBe('* [x] [asd](sdf)')
+ // Invalid ones but should be syntactical unchanged
+ expect(markdownThroughEditor('- [F] asd')).toBe('* [F] asd')
expect(markdownThroughEditor('- [ [asd](sdf)')).toBe('* [ [asd](sdf)')
+ // Valid, whitespace is allowed inside the checkbox
+ expect(markdownThroughEditor('- [\t] asd')).toBe('* [ ] asd')
expect(markdownThroughEditor('- [ ] asd')).toBe('* [ ] asd')
+ // Valid ones
+ expect(markdownThroughEditor('- [ ] [asd](sdf)')).toBe('* [ ] [asd](sdf)')
+ expect(markdownThroughEditor('- [x] [asd](sdf)')).toBe('* [x] [asd](sdf)')
expect(markdownThroughEditor('- [ ] foo\n- [x] bar')).toBe('* [ ] foo\n* [x] bar')
expect(markdownThroughEditor('- [x] foo\n' +
' - [ ] bar\n' +
@@ -109,10 +114,12 @@ describe('Markdown though editor', () => {
' * [x] baz\n' +
'* [ ] bim')
expect(markdownThroughEditor('- [X] asd')).toBe('* [x] asd')
- expect(markdownThroughEditor('- [\t] asd')).toBe('* [ ] asd')
- expect(markdownThroughEditor('- [ ] asd')).toBe('* [ ] asd')
expect(markdownThroughEditor('- [X] asd')).toBe('* [x] asd')
- expect(markdownThroughEditor('- [F] asd')).toBe('* [F] asd')
+
+ expect(markdownThroughEditorHtml('<ul class="contains-task-list"><li><input type="checkbox" checked /><label>foo</label></li></ul>')).toBe('* [x] foo')
+ expect(markdownThroughEditorHtml('<ul class="contains-task-list"><li><input type="checkbox" /><label>test</label></li></ul>')).toBe('* [ ] test')
+ expect(markdownThroughEditorHtml('<ul class="contains-task-list"><li><input type="checkbox" checked /><div><h2>Test</h2><p><strong>content</strong></p></div></li></ul>')).toBe('* [x] Test\n\n **content**')
+ expect(markdownThroughEditorHtml('<ul class="contains-task-list"><li><input type="checkbox" checked /><p>Test</p><h1>Block level headline</h1></li></ul>')).toBe('* [x] Test\n\n # Block level headline')
})
test('horizontal rule', () => {
diff --git a/src/tests/markdownit.spec.js b/src/tests/markdownit.spec.js
index 30748860a..05669dab9 100644
--- a/src/tests/markdownit.spec.js
+++ b/src/tests/markdownit.spec.js
@@ -9,7 +9,7 @@ describe('markdownit', () => {
const rendered = markdownit.render('* [ ] task\n* not a task')
expect(stripIndent(rendered)).toBe(stripIndent(`
<ul class="contains-task-list">
- <li class="task-list-item"><input class="task-list-item-checkbox" disabled="" type="checkbox"> task</li>
+ <li class="task-list-item "><input class="task-list-item-checkbox" type="checkbox" disabled="" id="task-item-0" />task</li>
</ul>
<ul>
<li>not a task</li>
@@ -24,7 +24,7 @@ describe('markdownit', () => {
<li>not a task</li>
</ul>
<ul class="contains-task-list">
- <li class="task-list-item"><input class="task-list-item-checkbox" disabled="" type="checkbox"> task</li>
+ <li class="task-list-item "><input class="task-list-item-checkbox" type="checkbox" disabled="" id="task-item-1" />task</li>
</ul>
`))
})