diff --git a/core/modules/editor/operations/text/wrap-lines.js b/core/modules/editor/operations/text/wrap-lines.js index e034292c3..2e4f22943 100644 --- a/core/modules/editor/operations/text/wrap-lines.js +++ b/core/modules/editor/operations/text/wrap-lines.js @@ -15,16 +15,33 @@ Text editor operation to wrap the selected lines with a prefix and suffix exports["wrap-lines"] = function(event,operation) { var prefix = event.paramObject.prefix || "", suffix = event.paramObject.suffix || ""; - // Cut just past the preceding line break, or the start of the text - operation.cutStart = $tw.utils.findPrecedingLineBreak(operation.text,operation.selStart); - // Cut to just past the following line break, or to the end of the text - operation.cutEnd = $tw.utils.findFollowingLineBreak(operation.text,operation.selEnd); - // Add the prefix and suffix - operation.replacement = prefix + "\n" + - operation.text.substring(operation.cutStart,operation.cutEnd) + "\n" + - suffix + "\n"; - operation.newSelStart = operation.cutStart + prefix.length + 1; - operation.newSelEnd = operation.newSelStart + (operation.cutEnd - operation.cutStart); + if($tw.utils.endsWith(operation.text.substring(0,operation.selStart), prefix + "\n") && + $tw.utils.startsWith(operation.text.substring(operation.selEnd), "\n" + suffix)) { + // Selected text is already surrounded by prefix and suffix: Remove them + // Cut selected text plus prefix and suffix + operation.cutStart = operation.selStart - (prefix.length + 1); + operation.cutEnd = operation.selEnd + suffix.length + 1; + // Also cut the following newline (if there is any) + if (operation.text[operation.cutEnd] === "\n") { + operation.cutEnd++; + } + // Replace with selection + operation.replacement = operation.text.substring(operation.selStart,operation.selEnd); + // Select text that was in between prefix and suffix + operation.newSelStart = operation.cutStart; + operation.newSelEnd = operation.selEnd - (prefix.length + 1); + } else { + // Cut just past the preceding line break, or the start of the text + operation.cutStart = $tw.utils.findPrecedingLineBreak(operation.text,operation.selStart); + // Cut to just past the following line break, or to the end of the text + operation.cutEnd = $tw.utils.findFollowingLineBreak(operation.text,operation.selEnd); + // Add the prefix and suffix + operation.replacement = prefix + "\n" + + operation.text.substring(operation.cutStart,operation.cutEnd) + "\n" + + suffix + "\n"; + operation.newSelStart = operation.cutStart + prefix.length + 1; + operation.newSelEnd = operation.newSelStart + (operation.cutEnd - operation.cutStart); + } }; })(); diff --git a/core/modules/utils/utils.js b/core/modules/utils/utils.js index 441eb638f..bc4774fe1 100644 --- a/core/modules/utils/utils.js +++ b/core/modules/utils/utils.js @@ -95,6 +95,20 @@ exports.repeat = function(str,count) { return result; }; +/* +Check if a string starts with another string +*/ +exports.startsWith = function(str,search) { + return str.substring(0, search.length) === search; +}; + +/* +Check if a string ends with another string +*/ +exports.endsWith = function(str,search) { + return str.substring(str.length - search.length) === search; +}; + /* Trim whitespace from the start and end of a string Thanks to Steven Levithan, http://blog.stevenlevithan.com/archives/faster-trim-javascript