mirror of https://github.com/vector-im/riot-web
Mimic ctrl+j of RT mode in MD mode
by inspecting whether multiple lines are selected or the selection is empty. If either of these are true, insert a code block surrounding the selection, otherwise insert single backticks around the selection for inline code formatting.pull/21833/head
parent
b9dfaf777e
commit
28c98d93d1
|
@ -304,3 +304,14 @@ export function attachImmutableEntitiesToEmoji(editorState: EditorState): Editor
|
||||||
|
|
||||||
return editorState;
|
return editorState;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function hasMultiLineSelection(editorState: EditorState): boolean {
|
||||||
|
const selectionState = editorState.getSelection();
|
||||||
|
const anchorKey = selectionState.getAnchorKey();
|
||||||
|
const currentContent = editorState.getCurrentContent();
|
||||||
|
const currentContentBlock = currentContent.getBlockForKey(anchorKey);
|
||||||
|
const start = selectionState.getStartOffset();
|
||||||
|
const end = selectionState.getEndOffset();
|
||||||
|
const selectedText = currentContentBlock.getText().slice(start, end);
|
||||||
|
return selectedText.includes('\n');
|
||||||
|
}
|
||||||
|
|
|
@ -521,14 +521,12 @@ export default class MessageComposerInput extends React.Component {
|
||||||
this.enableRichtext(!this.state.isRichtextEnabled);
|
this.enableRichtext(!this.state.isRichtextEnabled);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
let newState: ?EditorState = null;
|
let newState: ?EditorState = null;
|
||||||
|
|
||||||
// Draft handles rich text mode commands by default but we need to do it ourselves for Markdown.
|
// Draft handles rich text mode commands by default but we need to do it ourselves for Markdown.
|
||||||
if (this.state.isRichtextEnabled) {
|
if (this.state.isRichtextEnabled) {
|
||||||
// These are block types, not handled by RichUtils by default.
|
// These are block types, not handled by RichUtils by default.
|
||||||
const blockCommands = ['code-block', 'blockquote', 'unordered-list-item', 'ordered-list-item'];
|
const blockCommands = ['code-block', 'blockquote', 'unordered-list-item', 'ordered-list-item'];
|
||||||
|
|
||||||
if (blockCommands.includes(command)) {
|
if (blockCommands.includes(command)) {
|
||||||
this.setState({
|
this.setState({
|
||||||
editorState: RichUtils.toggleBlockType(this.state.editorState, command),
|
editorState: RichUtils.toggleBlockType(this.state.editorState, command),
|
||||||
|
@ -540,14 +538,26 @@ export default class MessageComposerInput extends React.Component {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
let contentState = this.state.editorState.getCurrentContent();
|
const contentState = this.state.editorState.getCurrentContent();
|
||||||
|
const multipleLinesSelected = RichText.hasMultiLineSelection(this.state.editorState);
|
||||||
|
|
||||||
|
const selectionState = this.state.editorState.getSelection();
|
||||||
|
const start = selectionState.getStartOffset();
|
||||||
|
const end = selectionState.getEndOffset();
|
||||||
|
|
||||||
|
// If multiple lines are selected or nothing is selected, insert a code block
|
||||||
|
// instead of applying inline code formatting. This is an attempt to mimic what
|
||||||
|
// happens in non-MD mode.
|
||||||
|
const treatInlineCodeAsBlock = multipleLinesSelected || start === end;
|
||||||
|
const textMdCodeBlock = (text) => `\`\`\`\n${text}\n\`\`\`\n`;
|
||||||
const modifyFn = {
|
const modifyFn = {
|
||||||
'bold': (text) => `**${text}**`,
|
'bold': (text) => `**${text}**`,
|
||||||
'italic': (text) => `*${text}*`,
|
'italic': (text) => `*${text}*`,
|
||||||
'underline': (text) => `<u>${text}</u>`,
|
'underline': (text) => `<u>${text}</u>`,
|
||||||
'strike': (text) => `<del>${text}</del>`,
|
'strike': (text) => `<del>${text}</del>`,
|
||||||
'code-block': (text) => `\`\`\`\n${text}\n\`\`\`\n`,
|
// ("code" is triggered by ctrl+j by draft-js by default)
|
||||||
|
'code': (text) => treatInlineCodeAsBlock ? textMdCodeBlock(text) : `\`${text}\``,
|
||||||
|
'code-block': textMdCodeBlock,
|
||||||
'blockquote': (text) => text.split('\n').map((line) => `> ${line}\n`).join('') + '\n',
|
'blockquote': (text) => text.split('\n').map((line) => `> ${line}\n`).join('') + '\n',
|
||||||
'unordered-list-item': (text) => text.split('\n').map((line) => `\n- ${line}`).join(''),
|
'unordered-list-item': (text) => text.split('\n').map((line) => `\n- ${line}`).join(''),
|
||||||
'ordered-list-item': (text) => text.split('\n').map((line, i) => `\n${i + 1}. ${line}`).join(''),
|
'ordered-list-item': (text) => text.split('\n').map((line, i) => `\n${i + 1}. ${line}`).join(''),
|
||||||
|
@ -558,6 +568,7 @@ export default class MessageComposerInput extends React.Component {
|
||||||
'italic': -1,
|
'italic': -1,
|
||||||
'underline': -4,
|
'underline': -4,
|
||||||
'strike': -6,
|
'strike': -6,
|
||||||
|
'code': treatInlineCodeAsBlock ? -5 : -1,
|
||||||
'code-block': -5,
|
'code-block': -5,
|
||||||
'blockquote': -2,
|
'blockquote': -2,
|
||||||
}[command];
|
}[command];
|
||||||
|
|
Loading…
Reference in New Issue