Merge pull request #1100 from thelounge/xpaw/0x04

Add support for 0x04 hex colors
This commit is contained in:
Pavel Djundik 2017-05-06 13:43:14 +03:00 committed by GitHub
commit 7ae364e360
3 changed files with 167 additions and 4 deletions

View File

@ -3,6 +3,7 @@
// Styling control codes // Styling control codes
const BOLD = "\x02"; const BOLD = "\x02";
const COLOR = "\x03"; const COLOR = "\x03";
const HEX_COLOR = "\x04";
const RESET = "\x0f"; const RESET = "\x0f";
const REVERSE = "\x16"; const REVERSE = "\x16";
const ITALIC = "\x1d"; const ITALIC = "\x1d";
@ -12,6 +13,9 @@ const UNDERLINE = "\x1f";
// integers, `XX` is the text color and `YY` is an optional background color. // integers, `XX` is the text color and `YY` is an optional background color.
const colorRx = /^(\d{1,2})(?:,(\d{1,2}))?/; const colorRx = /^(\d{1,2})(?:,(\d{1,2}))?/;
// 6-char Hex color code matcher
const hexColorRx = /^([0-9a-f]{6})(?:,([0-9a-f]{6}))?/i;
// Represents all other control codes that to be ignored/filtered from the text // Represents all other control codes that to be ignored/filtered from the text
const controlCodesRx = /[\u0000-\u001F]/g; const controlCodesRx = /[\u0000-\u001F]/g;
@ -26,12 +30,14 @@ function parseStyle(text) {
// At any given time, these carry style information since last time a styling // At any given time, these carry style information since last time a styling
// control code was met. // control code was met.
let colorCodes, bold, textColor, bgColor, reverse, italic, underline; let colorCodes, bold, textColor, bgColor, hexColor, hexBgColor, reverse, italic, underline;
const resetStyle = () => { const resetStyle = () => {
bold = false; bold = false;
textColor = undefined; textColor = undefined;
bgColor = undefined; bgColor = undefined;
hexColor = undefined;
hexBgColor = undefined;
reverse = false; reverse = false;
italic = false; italic = false;
underline = false; underline = false;
@ -57,6 +63,8 @@ function parseStyle(text) {
bold, bold,
textColor, textColor,
bgColor, bgColor,
hexColor,
hexBgColor,
reverse, reverse,
italic, italic,
underline, underline,
@ -113,6 +121,28 @@ function parseStyle(text) {
} }
break; break;
case HEX_COLOR:
emitFragment();
colorCodes = text.slice(position + 1).match(hexColorRx);
if (colorCodes) {
hexColor = colorCodes[1].toUpperCase();
if (colorCodes[2]) {
hexBgColor = colorCodes[2].toUpperCase();
}
// Color code length is > 1, so bump the current position cursor by as
// much (and reset the start cursor for the current text block as well)
position += colorCodes[0].length;
start = position + 1;
} else {
// If no color codes were found, toggles back to no colors (like BOLD).
hexColor = undefined;
hexBgColor = undefined;
}
break;
case REVERSE: case REVERSE:
emitFragment(); emitFragment();
reverse = !reverse; reverse = !reverse;
@ -139,7 +169,7 @@ function parseStyle(text) {
return result; return result;
} }
const properties = ["bold", "textColor", "bgColor", "italic", "underline", "reverse"]; const properties = ["bold", "textColor", "bgColor", "hexColor", "hexBgColor", "italic", "underline", "reverse"];
function prepare(text) { function prepare(text) {
return parseStyle(text) return parseStyle(text)

View File

@ -24,10 +24,24 @@ function createFragment(fragment) {
if (fragment.underline) { if (fragment.underline) {
classes.push("irc-underline"); classes.push("irc-underline");
} }
let attributes = classes.length ? ` class="${classes.join(" ")}"` : "";
const escapedText = Handlebars.Utils.escapeExpression(fragment.text); const escapedText = Handlebars.Utils.escapeExpression(fragment.text);
if (classes.length) {
return `<span class="${classes.join(" ")}">${escapedText}</span>`; if (fragment.hexColor) {
attributes += ` style="color:#${fragment.hexColor}`;
if (fragment.hexBgColor) {
attributes += `;background-color:#${fragment.hexBgColor}`;
} }
attributes += "\"";
}
if (attributes.length) {
return `<span${attributes}>${escapedText}</span>`;
}
return escapedText; return escapedText;
} }

View File

@ -10,6 +10,8 @@ describe("parseStyle", () => {
bold: false, bold: false,
textColor: undefined, textColor: undefined,
bgColor: undefined, bgColor: undefined,
hexColor: undefined,
hexBgColor: undefined,
reverse: false, reverse: false,
italic: false, italic: false,
underline: false, underline: false,
@ -30,6 +32,8 @@ describe("parseStyle", () => {
bold: true, bold: true,
textColor: undefined, textColor: undefined,
bgColor: undefined, bgColor: undefined,
hexColor: undefined,
hexBgColor: undefined,
reverse: false, reverse: false,
italic: false, italic: false,
underline: false, underline: false,
@ -50,6 +54,8 @@ describe("parseStyle", () => {
bold: false, bold: false,
textColor: 8, textColor: 8,
bgColor: undefined, bgColor: undefined,
hexColor: undefined,
hexBgColor: undefined,
reverse: false, reverse: false,
italic: false, italic: false,
underline: false, underline: false,
@ -69,6 +75,8 @@ describe("parseStyle", () => {
const expected = [{ const expected = [{
textColor: 4, textColor: 4,
bgColor: 8, bgColor: 8,
hexColor: undefined,
hexBgColor: undefined,
bold: false, bold: false,
reverse: false, reverse: false,
italic: false, italic: false,
@ -90,6 +98,8 @@ describe("parseStyle", () => {
bold: false, bold: false,
textColor: undefined, textColor: undefined,
bgColor: undefined, bgColor: undefined,
hexColor: undefined,
hexBgColor: undefined,
reverse: false, reverse: false,
italic: true, italic: true,
underline: false, underline: false,
@ -104,12 +114,101 @@ describe("parseStyle", () => {
expect(actual).to.deep.equal(expected); expect(actual).to.deep.equal(expected);
}); });
it("should parse hex colors", () => {
const input = "test \x04FFFFFFnice \x02\x04RES006 \x0303,04\x04ff00FFcolored\x04eeeaFF,001122 background\x04\x03\x02?";
const expected = [{
bold: false,
textColor: undefined,
bgColor: undefined,
hexColor: undefined,
hexBgColor: undefined,
reverse: false,
italic: false,
underline: false,
text: "test ",
start: 0,
end: 5
}, {
bold: false,
textColor: undefined,
bgColor: undefined,
hexColor: "FFFFFF",
hexBgColor: undefined,
reverse: false,
italic: false,
underline: false,
text: "nice ",
start: 5,
end: 10
}, {
bold: true,
textColor: undefined,
bgColor: undefined,
hexColor: undefined,
hexBgColor: undefined,
reverse: false,
italic: false,
underline: false,
text: "RES006 ",
start: 10,
end: 17
}, {
bold: true,
textColor: 3,
bgColor: 4,
hexColor: "FF00FF",
hexBgColor: undefined,
reverse: false,
italic: false,
underline: false,
text: "colored",
start: 17,
end: 24
}, {
bold: true,
textColor: 3,
bgColor: 4,
hexColor: "EEEAFF",
hexBgColor: "001122",
reverse: false,
italic: false,
underline: false,
text: " background",
start: 24,
end: 35
}, {
bold: false,
textColor: undefined,
bgColor: undefined,
hexColor: undefined,
hexBgColor: undefined,
reverse: false,
italic: false,
underline: false,
text: "?",
start: 35,
end: 36
}];
const actual = parseStyle(input);
expect(actual).to.deep.equal(expected);
});
it("should carry state corretly forward", () => { it("should carry state corretly forward", () => {
const input = "\x02bold\x038yellow\x02nonBold\x03default"; const input = "\x02bold\x038yellow\x02nonBold\x03default";
const expected = [{ const expected = [{
bold: true, bold: true,
textColor: undefined, textColor: undefined,
bgColor: undefined, bgColor: undefined,
hexColor: undefined,
hexBgColor: undefined,
reverse: false, reverse: false,
italic: false, italic: false,
underline: false, underline: false,
@ -121,6 +220,8 @@ describe("parseStyle", () => {
bold: true, bold: true,
textColor: 8, textColor: 8,
bgColor: undefined, bgColor: undefined,
hexColor: undefined,
hexBgColor: undefined,
reverse: false, reverse: false,
italic: false, italic: false,
underline: false, underline: false,
@ -132,6 +233,8 @@ describe("parseStyle", () => {
bold: false, bold: false,
textColor: 8, textColor: 8,
bgColor: undefined, bgColor: undefined,
hexColor: undefined,
hexBgColor: undefined,
reverse: false, reverse: false,
italic: false, italic: false,
underline: false, underline: false,
@ -143,6 +246,8 @@ describe("parseStyle", () => {
bold: false, bold: false,
textColor: undefined, textColor: undefined,
bgColor: undefined, bgColor: undefined,
hexColor: undefined,
hexBgColor: undefined,
reverse: false, reverse: false,
italic: false, italic: false,
underline: false, underline: false,
@ -163,6 +268,8 @@ describe("parseStyle", () => {
bold: true, bold: true,
textColor: undefined, textColor: undefined,
bgColor: undefined, bgColor: undefined,
hexColor: undefined,
hexBgColor: undefined,
reverse: false, reverse: false,
italic: false, italic: false,
underline: false, underline: false,
@ -174,6 +281,8 @@ describe("parseStyle", () => {
bold: false, bold: false,
textColor: undefined, textColor: undefined,
bgColor: undefined, bgColor: undefined,
hexColor: undefined,
hexBgColor: undefined,
reverse: false, reverse: false,
italic: false, italic: false,
underline: false, underline: false,
@ -185,6 +294,8 @@ describe("parseStyle", () => {
bold: true, bold: true,
textColor: undefined, textColor: undefined,
bgColor: undefined, bgColor: undefined,
hexColor: undefined,
hexBgColor: undefined,
reverse: false, reverse: false,
italic: false, italic: false,
underline: false, underline: false,
@ -205,6 +316,8 @@ describe("parseStyle", () => {
bold: true, bold: true,
textColor: 4, textColor: 4,
bgColor: undefined, bgColor: undefined,
hexColor: undefined,
hexBgColor: undefined,
reverse: true, reverse: true,
italic: true, italic: true,
underline: true, underline: true,
@ -216,6 +329,8 @@ describe("parseStyle", () => {
bold: false, bold: false,
textColor: undefined, textColor: undefined,
bgColor: undefined, bgColor: undefined,
hexColor: undefined,
hexBgColor: undefined,
reverse: false, reverse: false,
italic: false, italic: false,
underline: false, underline: false,
@ -236,6 +351,8 @@ describe("parseStyle", () => {
bold: false, bold: false,
textColor: undefined, textColor: undefined,
bgColor: undefined, bgColor: undefined,
hexColor: undefined,
hexBgColor: undefined,
reverse: false, reverse: false,
italic: false, italic: false,
underline: false, underline: false,
@ -258,6 +375,8 @@ describe("parseStyle", () => {
bold: false, bold: false,
textColor: 12, textColor: 12,
bgColor: undefined, bgColor: undefined,
hexColor: undefined,
hexBgColor: undefined,
reverse: false, reverse: false,
italic: false, italic: false,
underline: false, underline: false,