diff --git a/src/editor/deserialize.js b/src/editor/deserialize.js index 925d0d1ab3..04edd4541c 100644 --- a/src/editor/deserialize.js +++ b/src/editor/deserialize.js @@ -76,7 +76,7 @@ function parseHeader(el, partCreator) { return partCreator.plain("#".repeat(depth) + " "); } -function parseElement(n, partCreator, state) { +function parseElement(n, partCreator, lastNode, state) { switch (n.nodeName) { case "H1": case "H2": @@ -90,7 +90,7 @@ function parseElement(n, partCreator, state) { case "BR": return partCreator.newline(); case "EM": - return partCreator.plain(`*${n.textContent}*`); + return partCreator.plain(`_${n.textContent}_`); case "STRONG": return partCreator.plain(`**${n.textContent}**`); case "PRE": @@ -107,6 +107,12 @@ function parseElement(n, partCreator, state) { return partCreator.plain(`${indent}- `); } } + case "P": { + if (lastNode) { + return partCreator.newline(); + } + break; + } case "OL": case "UL": state.listDepth = (state.listDepth || 0) + 1; @@ -183,7 +189,7 @@ function parseHtmlMessage(html, partCreator, isQuotedMessage) { if (n.nodeType === Node.TEXT_NODE) { newParts.push(...parseAtRoomMentions(n.nodeValue, partCreator)); } else if (n.nodeType === Node.ELEMENT_NODE) { - const parseResult = parseElement(n, partCreator, state); + const parseResult = parseElement(n, partCreator, lastNode, state); if (parseResult) { if (Array.isArray(parseResult)) { newParts.push(...parseResult); @@ -200,10 +206,6 @@ function parseHtmlMessage(html, partCreator, isQuotedMessage) { parts.push(...newParts); - // extra newline after quote, only if there something behind it... - if (lastNode && lastNode.nodeName === "BLOCKQUOTE") { - parts.push(partCreator.newline()); - } const decend = checkDecendInto(n); // when not decending (like for PRE), onNodeLeave won't be called to set lastNode // so do that here. diff --git a/test/editor/deserialize-test.js b/test/editor/deserialize-test.js index 8a79b4101f..bf670b0fd8 100644 --- a/test/editor/deserialize-test.js +++ b/test/editor/deserialize-test.js @@ -94,7 +94,7 @@ describe('editor/deserialize', function() { const html = "bold and emphasized text"; const parts = normalize(parseEvent(htmlMessage(html), createPartCreator())); expect(parts.length).toBe(1); - expect(parts[0]).toStrictEqual({type: "plain", text: "**bold** and *emphasized* text"}); + expect(parts[0]).toStrictEqual({type: "plain", text: "**bold** and _emphasized_ text"}); }); it('hyperlink', function() { const html = 'click this!'; @@ -105,10 +105,11 @@ describe('editor/deserialize', function() { it('multiple lines with paragraphs', function() { const html = '

hello

world

'; const parts = normalize(parseEvent(htmlMessage(html), createPartCreator())); - expect(parts.length).toBe(3); + expect(parts.length).toBe(4); expect(parts[0]).toStrictEqual({type: "plain", text: "hello"}); expect(parts[1]).toStrictEqual({type: "newline", text: "\n"}); - expect(parts[2]).toStrictEqual({type: "plain", text: "world"}); + expect(parts[2]).toStrictEqual({type: "newline", text: "\n"}); + expect(parts[3]).toStrictEqual({type: "plain", text: "world"}); }); it('multiple lines with line breaks', function() { const html = 'hello
world'; @@ -121,18 +122,19 @@ describe('editor/deserialize', function() { it('multiple lines mixing paragraphs and line breaks', function() { const html = '

hello
warm

world

'; const parts = normalize(parseEvent(htmlMessage(html), createPartCreator())); - expect(parts.length).toBe(5); + expect(parts.length).toBe(6); expect(parts[0]).toStrictEqual({type: "plain", text: "hello"}); expect(parts[1]).toStrictEqual({type: "newline", text: "\n"}); expect(parts[2]).toStrictEqual({type: "plain", text: "warm"}); expect(parts[3]).toStrictEqual({type: "newline", text: "\n"}); - expect(parts[4]).toStrictEqual({type: "plain", text: "world"}); + expect(parts[4]).toStrictEqual({type: "newline", text: "\n"}); + expect(parts[5]).toStrictEqual({type: "plain", text: "world"}); }); it('quote', function() { const html = '

wise
words

indeed

'; const parts = normalize(parseEvent(htmlMessage(html), createPartCreator())); expect(parts.length).toBe(6); - expect(parts[0]).toStrictEqual({type: "plain", text: "> *wise*"}); + expect(parts[0]).toStrictEqual({type: "plain", text: "> _wise_"}); expect(parts[1]).toStrictEqual({type: "newline", text: "\n"}); expect(parts[2]).toStrictEqual({type: "plain", text: "> **words**"}); expect(parts[3]).toStrictEqual({type: "newline", text: "\n"}); @@ -159,7 +161,7 @@ describe('editor/deserialize', function() { const html = "formatted message for @room"; const parts = normalize(parseEvent(htmlMessage(html), createPartCreator())); expect(parts.length).toBe(2); - expect(parts[0]).toStrictEqual({type: "plain", text: "*formatted* message for "}); + expect(parts[0]).toStrictEqual({type: "plain", text: "_formatted_ message for "}); expect(parts[1]).toStrictEqual({type: "at-room-pill", text: "@room"}); }); it('inline code', function() { @@ -220,7 +222,7 @@ describe('editor/deserialize', function() { const html = "says DON'T SHOUT!"; const parts = normalize(parseEvent(htmlMessage(html, "m.emote"), createPartCreator())); expect(parts.length).toBe(1); - expect(parts[0]).toStrictEqual({type: "plain", text: "/me says *DON'T SHOUT*!"}); + expect(parts[0]).toStrictEqual({type: "plain", text: "/me says _DON'T SHOUT_!"}); }); }); });