Skip to content
This repository has been archived by the owner on Sep 11, 2024. It is now read-only.

Commit

Permalink
Treat lists with a single empty item as plain text, not Markdown.
Browse files Browse the repository at this point in the history
This allows users to send simple messages such as `-`, `+`, `*` and
`2021.` without Element Web mangling them into a nonsensical empty list.
As soon as any non-whitespace content is added to the item, it switches
back to treating it as a list of one item.

Fixes vector-im/element-web#7631.
  • Loading branch information
dkasak committed Sep 17, 2021
1 parent 05971e0 commit d10464a
Show file tree
Hide file tree
Showing 2 changed files with 41 additions and 0 deletions.
19 changes: 19 additions & 0 deletions src/Markdown.ts
Original file line number Diff line number Diff line change
Expand Up @@ -80,12 +80,30 @@ export default class Markdown {
isPlainText(): boolean {
const walker = this.parsed.walker();

let emptyItemWithNoSiblings = (node: Node) => {
return !node.prev && !node.next && !node.firstChild
}

let ev;
while ( (ev = walker.next()) ) {
const node = ev.node;
if (TEXT_NODES.indexOf(node.type) > -1) {
// definitely text
continue;
} else if (node.type == 'list' || node.type == 'item') {
// Special handling for inputs like `+`, `*`, `-` and `2021.` which
// would otherwise be treated as a list of a single empty item.
// See https://github.com/vector-im/element-web/issues/7631
if (node.type == 'list' && emptyItemWithNoSiblings(node.firstChild)) {
// A list with a single empty item is treated as plain text.
continue;
} else if (node.type == 'item' && emptyItemWithNoSiblings(node)) {
// An empty list item with no sibling items is treated as plain text.
continue;
} else {
// Everything else is actual lists and therefore not plaintext.
return false;
}
} else if (node.type == 'html_inline' || node.type == 'html_block') {
// if it's an allowed html tag, we need to render it and therefore
// we will need to use HTML. If it's not allowed, it's not HTML since
Expand All @@ -97,6 +115,7 @@ export default class Markdown {
return false;
}
}

return true;
}

Expand Down
22 changes: 22 additions & 0 deletions test/editor/serialize-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,28 @@ describe('editor/serialize', function() {
const html = htmlSerializeIfNeeded(model, {});
expect(html).toBe("<em>hello</em> world");
});
it('lists with a single empty item are not considered markdown', function() {
const pc = createPartCreator();

const model1 = new EditorModel([pc.plain("-")]);
const html1 = htmlSerializeIfNeeded(model1, {});
expect(html1).toBe(undefined);

const model2 = new EditorModel([pc.plain("* ")]);
const html2 = htmlSerializeIfNeeded(model2, {});
expect(html2).toBe(undefined);

const model3 = new EditorModel([pc.plain("2021.")]);
const html3 = htmlSerializeIfNeeded(model3, {});
expect(html3).toBe(undefined);

});
it('lists with a single non-empty item are still markdown', function() {
const pc = createPartCreator();
const model = new EditorModel([pc.plain("2021. foo")]);
const html = htmlSerializeIfNeeded(model, {});
expect(html).toBe("<ol start=\"2021\">\n<li>foo</li>\n</ol>\n");
});
it('displaynames ending in a backslash work', function() {
const pc = createPartCreator();
const model = new EditorModel([pc.userPill("Displayname\\", "@user:server")]);
Expand Down

0 comments on commit d10464a

Please sign in to comment.