From a5a3e4e9150090e8bc2cc031b548125a56bf103a Mon Sep 17 00:00:00 2001 From: Pedro Ferreira Date: Sat, 11 Jun 2016 23:13:57 +0200 Subject: [PATCH] Basic Markdown highlighting --- src/RichText.js | 37 ++++++++++++++++++- .../views/rooms/MessageComposerInput.js | 16 ++++---- 2 files changed, 43 insertions(+), 10 deletions(-) diff --git a/src/RichText.js b/src/RichText.js index f1f2188d0d..2334bbf2d6 100644 --- a/src/RichText.js +++ b/src/RichText.js @@ -52,7 +52,7 @@ const ROOM_REGEX = /#\S+:\S+/g; /** * Returns a composite decorator which has access to provided scope. */ -export function getScopedDecorator(scope: any): CompositeDecorator { +export function getScopedRTDecorators(scope: any): CompositeDecorator { let MemberAvatar = sdk.getComponent('avatars.MemberAvatar'); let usernameDecorator = { @@ -78,9 +78,42 @@ export function getScopedDecorator(scope: any): CompositeDecorator { } }; - return new CompositeDecorator([usernameDecorator, roomDecorator]); + return [usernameDecorator, roomDecorator]; } +export function getScopedMDDecorators(scope: any): CompositeDecorator { + let markdownDecorators = ['BOLD', 'ITALIC'].map( + (style) => ({ + strategy: (contentBlock, callback) => { + return findWithRegex(MARKDOWN_REGEX[style], contentBlock, callback); + }, + component: (props) => ( + + {props.children} + + ) + })); + + markdownDecorators.push({ + strategy: (contentBlock, callback) => { + return findWithRegex(MARKDOWN_REGEX.LINK, contentBlock, callback); + }, + component: (props) => ( + + {props.children} + + ) + }); + + return markdownDecorators; +} + +const MARKDOWN_REGEX = { + LINK: /(?:\[([^\]]+)\]\(([^\)]+)\))|\<(\w+:\/\/[^\>]+)\>/g, + ITALIC: /([\*_])([\w\s]+?)\1/g, + BOLD: /([\*_])\1([\w\s]+?)\1\1/g +}; + /** * Utility function that looks for regex matches within a ContentBlock and invokes {callback} with (start, end) * From https://facebook.github.io/draft-js/docs/advanced-topics-decorators.html diff --git a/src/components/views/rooms/MessageComposerInput.js b/src/components/views/rooms/MessageComposerInput.js index 3c5ddf1512..eb096d5bc3 100644 --- a/src/components/views/rooms/MessageComposerInput.js +++ b/src/components/views/rooms/MessageComposerInput.js @@ -99,10 +99,10 @@ export default class MessageComposerInput extends React.Component { */ createEditorState(contentState: ?ContentState): EditorState { let func = contentState ? EditorState.createWithContent : EditorState.createEmpty; + const decoratorFunc = this.state.isRichtextEnabled ? RichText.getScopedRTDecorators : + RichText.getScopedMDDecorators; let args = contentState ? [contentState] : []; - if(this.state.isRichtextEnabled) { - args.push(RichText.getScopedDecorator(this.props)); - } + args.push(new CompositeDecorator(decoratorFunc(this.props))); return func(...args); } @@ -341,11 +341,7 @@ export default class MessageComposerInput extends React.Component { } enableRichtext(enabled: boolean) { - this.setState({ - isRichtextEnabled: enabled - }); - - if(!this.state.isRichtextEnabled) { + if(enabled) { let html = mdownToHtml(this.state.editorState.getCurrentContent().getPlainText()); this.setState({ editorState: this.createEditorState(RichText.HTMLtoContentState(html)) @@ -357,6 +353,10 @@ export default class MessageComposerInput extends React.Component { editorState: this.createEditorState(contentState) }); } + + this.setState({ + isRichtextEnabled: enabled + }); } handleKeyCommand(command: string): boolean {