diff --git a/client/js/libs/handlebars/ircmessageparser/parseStyle.js b/client/js/libs/handlebars/ircmessageparser/parseStyle.js
index d23d5bd6..a0f3fd08 100644
--- a/client/js/libs/handlebars/ircmessageparser/parseStyle.js
+++ b/client/js/libs/handlebars/ircmessageparser/parseStyle.js
@@ -3,6 +3,7 @@
// Styling control codes
const BOLD = "\x02";
const COLOR = "\x03";
+const HEX_COLOR = "\x04";
const RESET = "\x0f";
const REVERSE = "\x16";
const ITALIC = "\x1d";
@@ -12,6 +13,9 @@ const UNDERLINE = "\x1f";
// integers, `XX` is the text color and `YY` is an optional background color.
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
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
// control code was met.
- let colorCodes, bold, textColor, bgColor, reverse, italic, underline;
+ let colorCodes, bold, textColor, bgColor, hexColor, hexBgColor, reverse, italic, underline;
const resetStyle = () => {
bold = false;
textColor = undefined;
bgColor = undefined;
+ hexColor = undefined;
+ hexBgColor = undefined;
reverse = false;
italic = false;
underline = false;
@@ -57,6 +63,8 @@ function parseStyle(text) {
bold,
textColor,
bgColor,
+ hexColor,
+ hexBgColor,
reverse,
italic,
underline,
@@ -113,6 +121,28 @@ function parseStyle(text) {
}
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:
emitFragment();
reverse = !reverse;
@@ -139,7 +169,7 @@ function parseStyle(text) {
return result;
}
-const properties = ["bold", "textColor", "bgColor", "italic", "underline", "reverse"];
+const properties = ["bold", "textColor", "bgColor", "hexColor", "hexBgColor", "italic", "underline", "reverse"];
function prepare(text) {
return parseStyle(text)
diff --git a/client/js/libs/handlebars/parse.js b/client/js/libs/handlebars/parse.js
index 915a432c..426cbe4f 100644
--- a/client/js/libs/handlebars/parse.js
+++ b/client/js/libs/handlebars/parse.js
@@ -24,10 +24,24 @@ function createFragment(fragment) {
if (fragment.underline) {
classes.push("irc-underline");
}
+
+ let attributes = classes.length ? ` class="${classes.join(" ")}"` : "";
const escapedText = Handlebars.Utils.escapeExpression(fragment.text);
- if (classes.length) {
- return `${escapedText}`;
+
+ if (fragment.hexColor) {
+ attributes += ` style="color:#${fragment.hexColor}`;
+
+ if (fragment.hexBgColor) {
+ attributes += `;background-color:#${fragment.hexBgColor}`;
+ }
+
+ attributes += "\"";
}
+
+ if (attributes.length) {
+ return `${escapedText}`;
+ }
+
return escapedText;
}
diff --git a/test/client/js/libs/handlebars/ircmessageparser/parseStyle.js b/test/client/js/libs/handlebars/ircmessageparser/parseStyle.js
index 6af289c4..e978cbcc 100644
--- a/test/client/js/libs/handlebars/ircmessageparser/parseStyle.js
+++ b/test/client/js/libs/handlebars/ircmessageparser/parseStyle.js
@@ -10,6 +10,8 @@ describe("parseStyle", () => {
bold: false,
textColor: undefined,
bgColor: undefined,
+ hexColor: undefined,
+ hexBgColor: undefined,
reverse: false,
italic: false,
underline: false,
@@ -30,6 +32,8 @@ describe("parseStyle", () => {
bold: true,
textColor: undefined,
bgColor: undefined,
+ hexColor: undefined,
+ hexBgColor: undefined,
reverse: false,
italic: false,
underline: false,
@@ -50,6 +54,8 @@ describe("parseStyle", () => {
bold: false,
textColor: 8,
bgColor: undefined,
+ hexColor: undefined,
+ hexBgColor: undefined,
reverse: false,
italic: false,
underline: false,
@@ -69,6 +75,8 @@ describe("parseStyle", () => {
const expected = [{
textColor: 4,
bgColor: 8,
+ hexColor: undefined,
+ hexBgColor: undefined,
bold: false,
reverse: false,
italic: false,
@@ -90,6 +98,8 @@ describe("parseStyle", () => {
bold: false,
textColor: undefined,
bgColor: undefined,
+ hexColor: undefined,
+ hexBgColor: undefined,
reverse: false,
italic: true,
underline: false,
@@ -104,12 +114,101 @@ describe("parseStyle", () => {
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", () => {
const input = "\x02bold\x038yellow\x02nonBold\x03default";
const expected = [{
bold: true,
textColor: undefined,
bgColor: undefined,
+ hexColor: undefined,
+ hexBgColor: undefined,
reverse: false,
italic: false,
underline: false,
@@ -121,6 +220,8 @@ describe("parseStyle", () => {
bold: true,
textColor: 8,
bgColor: undefined,
+ hexColor: undefined,
+ hexBgColor: undefined,
reverse: false,
italic: false,
underline: false,
@@ -132,6 +233,8 @@ describe("parseStyle", () => {
bold: false,
textColor: 8,
bgColor: undefined,
+ hexColor: undefined,
+ hexBgColor: undefined,
reverse: false,
italic: false,
underline: false,
@@ -143,6 +246,8 @@ describe("parseStyle", () => {
bold: false,
textColor: undefined,
bgColor: undefined,
+ hexColor: undefined,
+ hexBgColor: undefined,
reverse: false,
italic: false,
underline: false,
@@ -163,6 +268,8 @@ describe("parseStyle", () => {
bold: true,
textColor: undefined,
bgColor: undefined,
+ hexColor: undefined,
+ hexBgColor: undefined,
reverse: false,
italic: false,
underline: false,
@@ -174,6 +281,8 @@ describe("parseStyle", () => {
bold: false,
textColor: undefined,
bgColor: undefined,
+ hexColor: undefined,
+ hexBgColor: undefined,
reverse: false,
italic: false,
underline: false,
@@ -185,6 +294,8 @@ describe("parseStyle", () => {
bold: true,
textColor: undefined,
bgColor: undefined,
+ hexColor: undefined,
+ hexBgColor: undefined,
reverse: false,
italic: false,
underline: false,
@@ -205,6 +316,8 @@ describe("parseStyle", () => {
bold: true,
textColor: 4,
bgColor: undefined,
+ hexColor: undefined,
+ hexBgColor: undefined,
reverse: true,
italic: true,
underline: true,
@@ -216,6 +329,8 @@ describe("parseStyle", () => {
bold: false,
textColor: undefined,
bgColor: undefined,
+ hexColor: undefined,
+ hexBgColor: undefined,
reverse: false,
italic: false,
underline: false,
@@ -236,6 +351,8 @@ describe("parseStyle", () => {
bold: false,
textColor: undefined,
bgColor: undefined,
+ hexColor: undefined,
+ hexBgColor: undefined,
reverse: false,
italic: false,
underline: false,
@@ -258,6 +375,8 @@ describe("parseStyle", () => {
bold: false,
textColor: 12,
bgColor: undefined,
+ hexColor: undefined,
+ hexBgColor: undefined,
reverse: false,
italic: false,
underline: false,