Merge pull request #3288 from savef/fix-bold-and-italic-buttons

Improve the italic and bold buttons on multiline selections.
This commit is contained in:
Robin Ward 2015-03-26 10:46:45 -04:00
commit a30895e69d
1 changed files with 50 additions and 32 deletions

View File

@ -1542,57 +1542,75 @@
}; };
commandProto.doBold = function (chunk, postProcessing) { commandProto.doBold = function (chunk, postProcessing) {
return this.doBorI(chunk, postProcessing, 2, this.getString("boldexample")); return this.doSurroundLines(chunk, postProcessing, 2, this.getString("boldexample"));
}; };
commandProto.doItalic = function (chunk, postProcessing) { commandProto.doItalic = function (chunk, postProcessing) {
return this.doBorI(chunk, postProcessing, 1, this.getString("italicexample")); return this.doSurroundLines(chunk, postProcessing, 1, this.getString("italicexample"));
}; };
// chunk: The selected region that will be enclosed with */** commandProto.doSurroundLines = function(realChunk, postProcessing, nStars, fallbackText) {
realChunk.trimWhitespace();
// Look for stars before and after, absorb them into the selection.
var starsBefore = /(\**$)/.exec(realChunk.before)[0];
var starsAfter = /(^\**)/.exec(realChunk.after)[0];
realChunk.before = realChunk.before.replace(/(\**$)/, "");
realChunk.after = realChunk.after.replace(/(^\**)/, "");
var lines = (starsBefore + realChunk.selection + starsAfter).split("\n");
// Don't show the fallback text if more than one line is selected,
// it's probably a break between paragraphs.
if(lines.length > 1) {
fallbackText = ""
}
for(var i=0; i<lines.length; i++) {
// Split before, selection and after up.
var lineMatch = lines[i].match(/^(\**)(.*?)(\**)$/);
var newChunk = new Chunks();
newChunk.before = lineMatch[1];
newChunk.selection = lineMatch[2];
newChunk.after = lineMatch[3];
this.doSurroundLine(newChunk, postProcessing, nStars, fallbackText);
lines[i] = newChunk.before + newChunk.selection + newChunk.after;
}
realChunk.selection = lines.join("\n");
};
// chunk: The selected region that will be enclosed with * or **
// nStars: 1 for italics, 2 for bold // nStars: 1 for italics, 2 for bold
// insertText: If you just click the button without highlighting text, this gets inserted // fallbackText: If you just click the button without highlighting text, this gets inserted
commandProto.doBorI = function (chunk, postProcessing, nStars, insertText) { commandProto.doSurroundLine = function (chunk, postProcessing, nStars, fallbackText) {
// Get rid of whitespace
// Get rid of whitespace and fixup newlines.
chunk.trimWhitespace(); chunk.trimWhitespace();
chunk.selection = chunk.selection.replace(/\n{2,}/g, "\n");
// Look for stars before and after. Is the chunk already marked up? var minStars = Math.min(chunk.before.length, chunk.after.length);
// note that these regex matches cannot fail
var starsBefore = /(\**$)/.exec(chunk.before)[0];
var starsAfter = /(^\**)/.exec(chunk.after)[0];
var prevStars = Math.min(starsBefore.length, starsAfter.length);
// Remove stars if we have to since the button acts as a toggle. // Remove stars if we have to since the button acts as a toggle.
if ((prevStars >= nStars) && (prevStars != 2 || nStars != 1)) { if ((minStars >= nStars) && (minStars != 2 || nStars != 1)) {
chunk.before = chunk.before.replace(re("[*]{" + nStars + "}$", ""), ""); chunk.before = chunk.before.replace(re("[*]{" + nStars + "}$", ""), "");
chunk.after = chunk.after.replace(re("^[*]{" + nStars + "}", ""), ""); chunk.after = chunk.after.replace(re("^[*]{" + nStars + "}", ""), "");
} }
else if (!chunk.selection && starsAfter) {
// It's not really clear why this code is necessary. It just moves
// some arbitrary stuff around.
chunk.after = chunk.after.replace(/^([*_]*)/, "");
chunk.before = chunk.before.replace(/(\s?)$/, "");
var whitespace = re.$1;
chunk.before = chunk.before + starsAfter + whitespace;
}
else { else {
// In most cases, if you don't have any selected text and click the button // In most cases, if you don't have any selected text and click the button
// you'll get a selected, marked up region with the default text inserted. // you'll get a selected, marked up region with the default text inserted.
if (!chunk.selection && !starsAfter) { if (!chunk.selection && !chunk.after) {
chunk.selection = insertText; chunk.selection = fallbackText;
} }
// Add the true markup. // Only operate if it's not a blank line
var markup = nStars <= 1 ? "*" : "**"; // shouldn't the test be = ? if(chunk.selection) {
chunk.before = chunk.before + markup; // Add the true markup.
chunk.after = markup + chunk.after; var markup = nStars === 1 ? "*" : "**";
chunk.before = chunk.before + markup;
chunk.after = markup + chunk.after;
}
} }
return;
}; };
commandProto.stripLinkDefs = function (text, defsToAdd) { commandProto.stripLinkDefs = function (text, defsToAdd) {