From db3f0d298ab97af64c1e17924e9b4552960f25d7 Mon Sep 17 00:00:00 2001 From: David Baker Date: Fri, 23 Sep 2016 18:50:25 +0100 Subject: [PATCH 1/3] Make RTE mode use the new Markdown wrapper class Equivalent of https://github.com/matrix-org/matrix-react-sdk/pull/492 for rich text mode --- .../views/rooms/MessageComposerInput.js | 54 +++++++++---------- 1 file changed, 25 insertions(+), 29 deletions(-) diff --git a/src/components/views/rooms/MessageComposerInput.js b/src/components/views/rooms/MessageComposerInput.js index dac952a0c3..248241233f 100644 --- a/src/components/views/rooms/MessageComposerInput.js +++ b/src/components/views/rooms/MessageComposerInput.js @@ -15,17 +15,6 @@ limitations under the License. */ import React from 'react'; import type SyntheticKeyboardEvent from 'react/lib/SyntheticKeyboardEvent'; -import marked from 'marked'; -marked.setOptions({ - renderer: new marked.Renderer(), - gfm: true, - tables: true, - breaks: false, - pedantic: false, - sanitize: true, - smartLists: true, - smartypants: false, -}); import {Editor, EditorState, RichUtils, CompositeDecorator, convertFromRaw, convertToRaw, Modifier, EditorChangeType, @@ -50,6 +39,7 @@ import * as RichText from '../../../RichText'; import * as HtmlUtils from '../../../HtmlUtils'; import Autocomplete from './Autocomplete'; import {Completion} from "../../../autocomplete/Autocompleter"; +import Markdown from '../../../Markdown'; const TYPING_USER_TIMEOUT = 10000, TYPING_SERVER_TIMEOUT = 30000; @@ -64,12 +54,6 @@ function stateToMarkdown(state) { ''); // this is *not* a zero width space, trust me :) } -function mdownToHtml(mdown: string): string { - let html = marked(mdown) || ""; - html = html.trim(); - return html; -} - /* * The textInput part of the MessageComposer */ @@ -416,8 +400,8 @@ export default class MessageComposerInput extends React.Component { enableRichtext(enabled: boolean) { let contentState = null; if (enabled) { - const html = mdownToHtml(this.state.editorState.getCurrentContent().getPlainText()); - contentState = RichText.HTMLtoContentState(html); + const md = new Markdown(this.state.editorState.getCurrentContent().getPlainText()); + contentState = RichText.HTMLtoContentState(md.toHTML()); } else { let markdown = stateToMarkdown(this.state.editorState.getCurrentContent()); if (markdown[markdown.length - 1] === '\n') { @@ -499,7 +483,7 @@ export default class MessageComposerInput extends React.Component { if (!contentState.hasText()) { return true; } - + let contentText = contentState.getPlainText(), contentHTML; @@ -534,24 +518,36 @@ export default class MessageComposerInput extends React.Component { } if (this.state.isRichtextEnabled) { - contentHTML = RichText.contentStateToHTML(contentState); + contentHTML = HtmlUtils.stripParagraphs( + RichText.contentStateToHTML(contentState) + ); } else { - contentHTML = mdownToHtml(contentText); + const md = new Markdown(contentText); + if (!md.isPlainText()) { + contentHTML = md.toHTML(); + } } - contentHTML = HtmlUtils.stripParagraphs(contentHTML); - - let sendFn = this.client.sendHtmlMessage; + let sendHtmlFn = this.client.sendHtmlMessage; + let sendTextFn = this.client.sendTextMessage; if (contentText.startsWith('/me')) { contentText = contentText.replace('/me', ''); // bit of a hack, but the alternative would be quite complicated - contentHTML = contentHTML.replace('/me', ''); - sendFn = this.client.sendHtmlEmote; + if (contentHTML) contentHTML = contentHTML.replace('/me', ''); + sendHtmlFn = this.client.sendHtmlEmote; + sendTextFn = this.client.sendTextEmote; } - this.sentHistory.push(contentHTML); - let sendMessagePromise = sendFn.call(this.client, this.props.room.roomId, contentText, contentHTML); + this.sentHistory.push(contentHTML || contentText); + let sendMessagePromise; + if (contentHTML) { + sendMessagePromise = sendHtmlFn.call( + this.client, this.props.room.roomId, contentText, contentHTML + ); + } else { + sendMessagePromise = sendTextFn.call(this.client, this.props.room.roomId, contentText); + } sendMessagePromise.then(() => { dis.dispatch({ From bf037ed6c7c9d23b6ebdc610266ec43dcb0e2eec Mon Sep 17 00:00:00 2001 From: David Baker Date: Fri, 23 Sep 2016 19:09:32 +0100 Subject: [PATCH 2/3] Add comment --- src/components/views/rooms/MessageComposerInput.js | 1 + 1 file changed, 1 insertion(+) diff --git a/src/components/views/rooms/MessageComposerInput.js b/src/components/views/rooms/MessageComposerInput.js index 248241233f..016282a68b 100644 --- a/src/components/views/rooms/MessageComposerInput.js +++ b/src/components/views/rooms/MessageComposerInput.js @@ -539,6 +539,7 @@ export default class MessageComposerInput extends React.Component { sendTextFn = this.client.sendTextEmote; } + // XXX: We don't actually seem to use this history? this.sentHistory.push(contentHTML || contentText); let sendMessagePromise; if (contentHTML) { From bbfc05b0c08acfaef0fca42a3548889e16cc48d1 Mon Sep 17 00:00:00 2001 From: David Baker Date: Mon, 26 Sep 2016 10:20:56 +0100 Subject: [PATCH 3/3] Fix name of text emote sending & fix tests --- .../views/rooms/MessageComposerInput.js | 2 +- .../views/rooms/MessageComposerInput-test.js | 16 +++++++++------- test/test-utils.js | 1 + 3 files changed, 11 insertions(+), 8 deletions(-) diff --git a/src/components/views/rooms/MessageComposerInput.js b/src/components/views/rooms/MessageComposerInput.js index 016282a68b..d361a4ad95 100644 --- a/src/components/views/rooms/MessageComposerInput.js +++ b/src/components/views/rooms/MessageComposerInput.js @@ -536,7 +536,7 @@ export default class MessageComposerInput extends React.Component { // bit of a hack, but the alternative would be quite complicated if (contentHTML) contentHTML = contentHTML.replace('/me', ''); sendHtmlFn = this.client.sendHtmlEmote; - sendTextFn = this.client.sendTextEmote; + sendTextFn = this.client.sendEmoteMessage; } // XXX: We don't actually seem to use this history? diff --git a/test/components/views/rooms/MessageComposerInput-test.js b/test/components/views/rooms/MessageComposerInput-test.js index 126034a40b..fe59722bcb 100644 --- a/test/components/views/rooms/MessageComposerInput-test.js +++ b/test/components/views/rooms/MessageComposerInput-test.js @@ -68,15 +68,17 @@ describe('MessageComposerInput', () => { }); it('should not send messages when composer is empty', () => { - const spy = sinon.spy(client, 'sendHtmlMessage'); + const textSpy = sinon.spy(client, 'sendTextMessage'); + const htmlSpy = sinon.spy(client, 'sendHtmlMessage'); mci.enableRichtext(true); mci.handleReturn(sinon.stub()); - expect(spy.calledOnce).toEqual(false, 'should not send message'); + expect(textSpy.calledOnce).toEqual(false, 'should not send text message'); + expect(htmlSpy.calledOnce).toEqual(false, 'should not send html message'); }); it('should not change content unnecessarily on RTE -> Markdown conversion', () => { - const spy = sinon.spy(client, 'sendHtmlMessage'); + const spy = sinon.spy(client, 'sendTextMessage'); mci.enableRichtext(true); addTextToDraft('a'); mci.handleKeyCommand('toggle-mode'); @@ -87,7 +89,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'); @@ -97,7 +99,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()); @@ -106,7 +108,7 @@ describe('MessageComposerInput', () => { }); it('should send emoji messages in Markdown', () => { - const spy = sinon.spy(client, 'sendHtmlMessage'); + const spy = sinon.spy(client, 'sendTextMessage'); mci.enableRichtext(false); addTextToDraft('☹'); mci.handleReturn(sinon.stub()); @@ -139,7 +141,7 @@ describe('MessageComposerInput', () => { // }); it('should insert formatting characters in Markdown mode', () => { - const spy = sinon.spy(client, 'sendHtmlMessage'); + const spy = sinon.spy(client, 'sendTextMessage'); mci.enableRichtext(false); mci.handleKeyCommand('italic'); mci.handleReturn(sinon.stub()); diff --git a/test/test-utils.js b/test/test-utils.js index e4c01d5c52..9df623d732 100644 --- a/test/test-utils.js +++ b/test/test-utils.js @@ -54,6 +54,7 @@ export function stubClient() { }, setAccountData: sinon.stub(), sendTyping: sinon.stub().returns(q({})), + sendTextMessage: () => q({}), sendHtmlMessage: () => q({}), };