#1754 - implement strikethrough formatting, client keybinding, tests, and help section

This commit is contained in:
Logan Griswold 2017-12-03 02:52:49 +00:00 committed by Jérémie Astori
parent 2f47307437
commit 0643d3b4a3
No known key found for this signature in database
GPG key ID: B9A4F245CD67BDE8
7 changed files with 268 additions and 4 deletions

View file

@ -1947,6 +1947,10 @@ part/quit messages where we don't load previews (adds a blank line otherwise) */
text-decoration: underline;
}
.irc-strikethrough {
text-decoration: line-through;
}
.irc-italic {
font-style: italic;
}

View file

@ -72,6 +72,7 @@ const colorsHotkeys = {
u: "\x1F",
i: "\x1D",
o: "\x0F",
s: "\x1e",
};
for (const hotkey in colorsHotkeys) {

View file

@ -8,6 +8,7 @@ const RESET = "\x0f";
const REVERSE = "\x16";
const ITALIC = "\x1d";
const UNDERLINE = "\x1f";
const STRIKETHROUGH = "\x1e";
// Color code matcher, with format `XX,YY` where both `XX` and `YY` are
// integers, `XX` is the text color and `YY` is an optional background color.
@ -22,7 +23,7 @@ const controlCodesRx = /[\u0000-\u001F]/g;
// Converts a given text into an array of objects, each of them representing a
// similarly styled section of the text. Each object carries the `text`, style
// information (`bold`, `textColor`, `bgcolor`, `reverse`, `italic`,
// `underline`), and `start`/`end` cursors.
// `underline`, `strikethrough`), and `start`/`end` cursors.
function parseStyle(text) {
const result = [];
let start = 0;
@ -30,7 +31,7 @@ function parseStyle(text) {
// At any given time, these carry style information since last time a styling
// control code was met.
let colorCodes, bold, textColor, bgColor, hexColor, hexBgColor, reverse, italic, underline;
let colorCodes, bold, textColor, bgColor, hexColor, hexBgColor, reverse, italic, underline, strikethrough;
const resetStyle = () => {
bold = false;
@ -41,6 +42,7 @@ function parseStyle(text) {
reverse = false;
italic = false;
underline = false;
strikethrough = false;
};
resetStyle();
@ -68,6 +70,7 @@ function parseStyle(text) {
reverse,
italic,
underline,
strikethrough,
text: processedText,
start: fragmentStart,
end: fragmentStart + processedText.length,
@ -156,6 +159,11 @@ function parseStyle(text) {
emitFragment();
underline = !underline;
break;
case STRIKETHROUGH:
emitFragment();
strikethrough = !strikethrough;
break;
}
// Evaluate the next character at the next iteration
@ -168,7 +176,7 @@ function parseStyle(text) {
return result;
}
const properties = ["bold", "textColor", "bgColor", "hexColor", "hexBgColor", "italic", "underline", "reverse"];
const properties = ["bold", "textColor", "bgColor", "hexColor", "hexBgColor", "italic", "underline", "reverse", "strikethrough"];
function prepare(text) {
return parseStyle(text)

View file

@ -28,6 +28,9 @@ function createFragment(fragment) {
if (fragment.underline) {
classes.push("irc-underline");
}
if (fragment.strikethrough) {
classes.push("irc-strikethrough");
}
let attributes = classes.length ? ` class="${classes.join(" ")}"` : "";
const escapedText = Handlebars.Utils.escapeExpression(fragment.text);

View file

@ -65,6 +65,15 @@
</div>
</div>
<div class="help-item">
<div class="subject">
<kbd class="key-all">Ctrl</kbd><kbd class="key-apple">⌘</kbd> + <kbd>S</kbd>
</div>
<div class="description">
<p>Mark all text typed after this shortcut as struck through.</p>
</div>
</div>
<div class="help-item">
<div class="subject">
<kbd class="key-all">Ctrl</kbd><kbd class="key-apple">⌘</kbd> + <kbd>O</kbd>

View file

@ -15,6 +15,7 @@ describe("parseStyle", () => {
reverse: false,
italic: false,
underline: false,
strikethrough: false,
text: "textwithcontrolcodes",
start: 0,
@ -37,6 +38,7 @@ describe("parseStyle", () => {
reverse: false,
italic: false,
underline: false,
strikethrough: false,
text: "bold",
start: 0,
@ -48,6 +50,219 @@ describe("parseStyle", () => {
expect(actual).to.deep.equal(expected);
});
it("should parse strikethrough", () => {
const input = "\x1estrikethrough text\x1e";
const expected = [{
bold: false,
textColor: undefined,
bgColor: undefined,
hexColor: undefined,
hexBgColor: undefined,
reverse: false,
italic: false,
underline: false,
strikethrough: true,
text: "strikethrough text",
start: 0,
end: 18,
}];
const actual = parseStyle(input);
expect(actual).to.deep.equal(expected);
});
it("should parse strikethrough and italics", () => {
const input = "\x1ditalic formatting \x1ewith strikethrough\x1d no italic \x1e and vanilla";
const expected = [{
bold: false,
textColor: undefined,
bgColor: undefined,
hexColor: undefined,
hexBgColor: undefined,
reverse: false,
italic: true,
underline: false,
strikethrough: false,
text: "italic formatting ",
start: 0,
end: 18,
}, {
bold: false,
textColor: undefined,
bgColor: undefined,
hexColor: undefined,
hexBgColor: undefined,
reverse: false,
italic: true,
underline: false,
strikethrough: true,
text: "with strikethrough",
start: 18,
end: 36,
}, {
bold: false,
textColor: undefined,
bgColor: undefined,
hexColor: undefined,
hexBgColor: undefined,
reverse: false,
italic: false,
underline: false,
strikethrough: true,
text: " no italic ",
start: 36,
end: 47,
}, {
bold: false,
textColor: undefined,
bgColor: undefined,
hexColor: undefined,
hexBgColor: undefined,
reverse: false,
italic: false,
underline: false,
strikethrough: false,
text: " and vanilla",
start: 47,
end: 59,
}];
const actual = parseStyle(input);
expect(actual).to.deep.equal(expected);
});
it("should parse strikethrough and text colors", () => {
const input = "\x031,2text with color \x1eand strikethrough\x1e\x03";
const expected = [{
bold: false,
textColor: 1,
bgColor: 2,
hexColor: undefined,
hexBgColor: undefined,
reverse: false,
italic: false,
underline: false,
strikethrough: false,
text: "text with color ",
start: 0,
end: 16,
}, {
bold: false,
textColor: 1,
bgColor: 2,
hexColor: undefined,
hexBgColor: undefined,
reverse: false,
italic: false,
underline: false,
strikethrough: true,
text: "and strikethrough",
start: 16,
end: 33,
}];
const actual = parseStyle(input);
expect(actual).to.deep.equal(expected);
});
it("should correctly parse multiple unclosed format tokens", () => {
const input = "\x1e\x02\x1d\x033,4string with multiple unclosed formats";
const expected = [{
bold: true,
textColor: 3,
bgColor: 4,
hexColor: undefined,
hexBgColor: undefined,
reverse: false,
italic: true,
underline: false,
strikethrough: true,
text: "string with multiple unclosed formats",
start: 0,
end: 37,
}];
const actual = parseStyle(input);
expect(actual).to.deep.equal(expected);
});
it("should toggle strikethrough correctly", () => {
const input = "toggling \x1eon and \x1eoff and \x1eon again\x1e";
const expected = [{
bold: false,
textColor: undefined,
bgColor: undefined,
hexColor: undefined,
hexBgColor: undefined,
reverse: false,
italic: false,
underline: false,
strikethrough: false,
text: "toggling ",
start: 0,
end: 9,
}, {
bold: false,
textColor: undefined,
bgColor: undefined,
hexColor: undefined,
hexBgColor: undefined,
reverse: false,
italic: false,
underline: false,
strikethrough: true,
text: "on and ",
start: 9,
end: 16,
}, {
bold: false,
textColor: undefined,
bgColor: undefined,
hexColor: undefined,
hexBgColor: undefined,
reverse: false,
italic: false,
underline: false,
strikethrough: false,
text: "off and ",
start: 16,
end: 24,
}, {
bold: false,
textColor: undefined,
bgColor: undefined,
hexColor: undefined,
hexBgColor: undefined,
reverse: false,
italic: false,
underline: false,
strikethrough: true,
text: "on again",
start: 24,
end: 32,
}];
const actual = parseStyle(input);
expect(actual).to.deep.equal(expected);
});
it("should parse textColor", () => {
const input = "\x038yellowText";
const expected = [{
@ -59,6 +274,7 @@ describe("parseStyle", () => {
reverse: false,
italic: false,
underline: false,
strikethrough: false,
text: "yellowText",
start: 0,
@ -81,6 +297,7 @@ describe("parseStyle", () => {
reverse: false,
italic: false,
underline: false,
strikethrough: false,
text: "yellowBG redText",
start: 0,
@ -103,6 +320,7 @@ describe("parseStyle", () => {
reverse: false,
italic: true,
underline: false,
strikethrough: false,
text: "italic",
start: 0,
@ -125,6 +343,7 @@ describe("parseStyle", () => {
reverse: false,
italic: false,
underline: false,
strikethrough: false,
text: "test ",
start: 0,
@ -138,6 +357,7 @@ describe("parseStyle", () => {
reverse: false,
italic: false,
underline: false,
strikethrough: false,
text: "nice ",
start: 5,
@ -151,6 +371,7 @@ describe("parseStyle", () => {
reverse: false,
italic: false,
underline: false,
strikethrough: false,
text: "RES006 ",
start: 10,
@ -164,6 +385,7 @@ describe("parseStyle", () => {
reverse: false,
italic: false,
underline: false,
strikethrough: false,
text: "colored",
start: 17,
@ -177,6 +399,7 @@ describe("parseStyle", () => {
reverse: false,
italic: false,
underline: false,
strikethrough: false,
text: " background",
start: 24,
@ -190,6 +413,7 @@ describe("parseStyle", () => {
reverse: false,
italic: false,
underline: false,
strikethrough: false,
text: "?",
start: 35,
@ -212,6 +436,7 @@ describe("parseStyle", () => {
reverse: false,
italic: false,
underline: false,
strikethrough: false,
text: "bold",
start: 0,
@ -225,6 +450,7 @@ describe("parseStyle", () => {
reverse: false,
italic: false,
underline: false,
strikethrough: false,
text: "yellow",
start: 4,
@ -238,6 +464,7 @@ describe("parseStyle", () => {
reverse: false,
italic: false,
underline: false,
strikethrough: false,
text: "nonBold",
start: 10,
@ -251,6 +478,7 @@ describe("parseStyle", () => {
reverse: false,
italic: false,
underline: false,
strikethrough: false,
text: "default",
start: 17,
@ -273,6 +501,7 @@ describe("parseStyle", () => {
reverse: false,
italic: false,
underline: false,
strikethrough: false,
text: "bold",
start: 0,
@ -286,6 +515,7 @@ describe("parseStyle", () => {
reverse: false,
italic: false,
underline: false,
strikethrough: false,
text: " ",
start: 4,
@ -299,6 +529,7 @@ describe("parseStyle", () => {
reverse: false,
italic: false,
underline: false,
strikethrough: false,
text: "bold",
start: 5,
@ -311,7 +542,7 @@ describe("parseStyle", () => {
});
it("should reset all styles", () => {
const input = "\x02\x034\x16\x1d\x1ffull\x0fnone";
const input = "\x1e\x02\x034\x16\x1d\x1ffull\x0fnone";
const expected = [{
bold: true,
textColor: 4,
@ -321,6 +552,7 @@ describe("parseStyle", () => {
reverse: true,
italic: true,
underline: true,
strikethrough: true,
text: "full",
start: 0,
@ -334,6 +566,7 @@ describe("parseStyle", () => {
reverse: false,
italic: false,
underline: false,
strikethrough: false,
text: "none",
start: 4,
@ -356,6 +589,7 @@ describe("parseStyle", () => {
reverse: false,
italic: false,
underline: false,
strikethrough: false,
text: "a",
start: 0,
@ -380,6 +614,7 @@ describe("parseStyle", () => {
reverse: false,
italic: false,
underline: false,
strikethrough: false,
text: rawString,
start: 0,

View file

@ -235,6 +235,10 @@ describe("parse Handlebars helper", () => {
name: "underline",
input: "\x1funderline",
expected: '<span class="irc-underline">underline</span>',
}, {
name: "strikethrough",
input: "\x1estrikethrough",
expected: '<span class="irc-strikethrough">strikethrough</span>',
}, {
name: "resets",
input: "\x02bold\x038yellow\x02nonBold\x03default",