diff --git a/src/components/views/rooms/BasicMessageComposer.js b/src/components/views/rooms/BasicMessageComposer.js
index 2b4693646a..99e7b8ea07 100644
--- a/src/components/views/rooms/BasicMessageComposer.js
+++ b/src/components/views/rooms/BasicMessageComposer.js
@@ -24,7 +24,7 @@ import {setSelection} from '../../../editor/caret';
import {
formatRangeAsQuote,
formatRangeAsCode,
- formatInline,
+ toggleInlineFormat,
replaceRangeAndMoveCaret,
} from '../../../editor/operations';
import {getCaretOffsetAndText, getRangeForSelection} from '../../../editor/dom';
@@ -457,13 +457,13 @@ export default class BasicMessageEditor extends React.Component {
this.historyManager.ensureLastChangesPushed(this.props.model);
switch (action) {
case "bold":
- formatInline(range, "**");
+ toggleInlineFormat(range, "**");
break;
case "italics":
- formatInline(range, "*");
+ toggleInlineFormat(range, "*");
break;
case "strikethrough":
- formatInline(range, "", "");
+ toggleInlineFormat(range, "", "");
break;
case "code":
formatRangeAsCode(range);
diff --git a/src/editor/operations.js b/src/editor/operations.js
index 4645e7d805..e2661faf59 100644
--- a/src/editor/operations.js
+++ b/src/editor/operations.js
@@ -100,10 +100,27 @@ export function formatRangeAsCode(range) {
replaceRangeAndExpandSelection(range, parts);
}
-export function formatInline(range, prefix, suffix = prefix) {
+export function toggleInlineFormat(range, prefix, suffix = prefix) {
const {model, parts} = range;
const {partCreator} = model;
- parts.unshift(partCreator.plain(prefix));
- parts.push(partCreator.plain(suffix));
+
+ const isFormatted = parts.length &&
+ parts[0].text.startsWith(prefix) &&
+ parts[parts.length - 1].text.endsWith(suffix);
+
+ if (isFormatted) {
+ // remove prefix and suffix
+ const partWithoutPrefix = parts[0].serialize();
+ partWithoutPrefix.text = partWithoutPrefix.text.substr(prefix.length);
+ parts[0] = partCreator.deserializePart(partWithoutPrefix);
+
+ const partWithoutSuffix = parts[parts.length - 1].serialize();
+ const suffixPartText = partWithoutSuffix.text;
+ partWithoutSuffix.text = suffixPartText.substring(0, suffixPartText.length - suffix.length);
+ parts[parts.length - 1] = partCreator.deserializePart(partWithoutSuffix);
+ } else {
+ parts.unshift(partCreator.plain(prefix));
+ parts.push(partCreator.plain(suffix));
+ }
replaceRangeAndExpandSelection(range, parts);
}