From e7a2c3b975c96c2c12691a7fe41f46b21e6fcca3 Mon Sep 17 00:00:00 2001 From: Luke Barnard Date: Thu, 29 Jun 2017 18:08:57 +0100 Subject: [PATCH 1/3] Only send HTML when using RTE when necessary When there are no styled blocks or inline styles applied within blocks, just send text instead of HTML. Also, don't add
for the last

(the last block). Fixes https://github.com/vector-im/riot-web/issues/3147 --- src/HtmlUtils.js | 9 ++++-- .../views/rooms/MessageComposerInput.js | 31 ++++++++++++++++--- 2 files changed, 32 insertions(+), 8 deletions(-) diff --git a/src/HtmlUtils.js b/src/HtmlUtils.js index ee679391cc..747e18e679 100644 --- a/src/HtmlUtils.js +++ b/src/HtmlUtils.js @@ -85,7 +85,6 @@ export function charactersToImageNode(alt, useSvg, ...unicode) { export function processHtmlForSending(html: string): string { - const contentDiv = document.createElement('div'); contentDiv.innerHTML = html; @@ -94,10 +93,14 @@ export function processHtmlForSending(html: string): string { } let contentHTML = ""; - for (let i=0; i'; + contentHTML += element.innerHTML; + // Don't add a
for the last

+ if (i !== contentDiv.children.length - 1) { + contentHTML += '
'; + } } else if (element.tagName.toLowerCase() === 'pre') { // Replace "
\n" with "\n" within `

` tags because the 
is // redundant. This is a workaround for a bug in draft-js-export-html: diff --git a/src/components/views/rooms/MessageComposerInput.js b/src/components/views/rooms/MessageComposerInput.js index baa9761bd7..3e2748e382 100644 --- a/src/components/views/rooms/MessageComposerInput.js +++ b/src/components/views/rooms/MessageComposerInput.js @@ -512,9 +512,30 @@ export default class MessageComposerInput extends React.Component { } if (this.state.isRichtextEnabled) { - contentHTML = HtmlUtils.processHtmlForSending( - RichText.contentStateToHTML(contentState), - ); + // We should only send HTML if any block is styled or contains inline style + let shouldSendHTML = false; + const blocks = contentState.getBlocksAsArray(); + if (blocks.some((block) => block.getType() !== 'unstyled')) { + shouldSendHTML = true; + } else { + const characterLists = blocks.map((block) => block.getCharacterList()); + // For each block of characters, determine if any inline styles are applied + // and if yes, send HTML + characterLists.forEach((characters) => { + const numberOfStylesForCharacters = characters.map( + (character) => character.getStyle().toArray().length, + ).toArray(); + // If any character has more than 0 inline styles applied, send HTML + if (numberOfStylesForCharacters.some((styles) => styles > 0)) { + shouldSendHTML = true; + } + }); + } + if (shouldSendHTML) { + contentHTML = HtmlUtils.processHtmlForSending( + RichText.contentStateToHTML(contentState), + ); + } } else { const md = new Markdown(contentText); if (md.isPlainText()) { @@ -536,8 +557,8 @@ export default class MessageComposerInput extends React.Component { } this.historyManager.addItem( - this.state.isRichtextEnabled ? contentHTML : contentState.getPlainText(), - this.state.isRichtextEnabled ? 'html' : 'markdown'); + contentHTML ? contentHTML : contentText, + contentHTML ? 'html' : 'markdown'); let sendMessagePromise; if (contentHTML) { From 80a73a50f5b3c76ef48061f790cce5ae53d192f7 Mon Sep 17 00:00:00 2001 From: Luke Barnard Date: Fri, 30 Jun 2017 12:39:08 +0100 Subject: [PATCH 2/3] Update tests When sending the letter "a" we expect it to be sent as a text message when RTE is enabled because we now detect that there is no formatting or styled blocks in the composer. We also expect emoji to be sent as plaintext if there is no formatting --- test/components/views/rooms/MessageComposerInput-test.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/components/views/rooms/MessageComposerInput-test.js b/test/components/views/rooms/MessageComposerInput-test.js index e2e2836a50..a68f71857f 100644 --- a/test/components/views/rooms/MessageComposerInput-test.js +++ b/test/components/views/rooms/MessageComposerInput-test.js @@ -99,7 +99,7 @@ describe('MessageComposerInput', () => { }); it('should not change content unnecessarily on Markdown -> RTE conversion', () => { - const spy = sinon.spy(client, 'sendHtmlMessage'); + const spy = sinon.spy(client, 'sendTextMessage'); mci.enableRichtext(false); addTextToDraft('a'); mci.handleKeyCommand('toggle-mode'); @@ -110,7 +110,7 @@ describe('MessageComposerInput', () => { }); it('should send emoji messages in rich text', () => { - const spy = sinon.spy(client, 'sendHtmlMessage'); + const spy = sinon.spy(client, 'sendTextMessage'); mci.enableRichtext(true); addTextToDraft('☹'); mci.handleReturn(sinon.stub()); From 030358e764b4a4e54922051bb869280db9a8d44d Mon Sep 17 00:00:00 2001 From: Luke Barnard Date: Fri, 30 Jun 2017 12:56:19 +0100 Subject: [PATCH 3/3] Clarify test names --- test/components/views/rooms/MessageComposerInput-test.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/components/views/rooms/MessageComposerInput-test.js b/test/components/views/rooms/MessageComposerInput-test.js index a68f71857f..80fd158608 100644 --- a/test/components/views/rooms/MessageComposerInput-test.js +++ b/test/components/views/rooms/MessageComposerInput-test.js @@ -109,7 +109,7 @@ describe('MessageComposerInput', () => { expect(spy.args[0][1]).toEqual('a'); }); - it('should send emoji messages in rich text', () => { + it('should send emoji messages when rich text is enabled', () => { const spy = sinon.spy(client, 'sendTextMessage'); mci.enableRichtext(true); addTextToDraft('☹'); @@ -118,7 +118,7 @@ describe('MessageComposerInput', () => { expect(spy.calledOnce).toEqual(true, 'should send message'); }); - it('should send emoji messages in Markdown', () => { + it('should send emoji messages when Markdown is enabled', () => { const spy = sinon.spy(client, 'sendTextMessage'); mci.enableRichtext(false); addTextToDraft('☹');