diff --git a/client/js/libs/handlebars/parse.js b/client/js/libs/handlebars/parse.js
index a6d26df8..6303d895 100644
--- a/client/js/libs/handlebars/parse.js
+++ b/client/js/libs/handlebars/parse.js
@@ -1,8 +1,9 @@
Handlebars.registerHelper(
"parse", function(text) {
var wrap = wraplong(text);
- text = escape(text);
+ text = Handlebars.Utils.escapeExpression(text);
text = colors(text);
+ text = channels(text);
text = uri(text);
if (wrap) {
return "" + text + "";
@@ -23,17 +24,6 @@ function wraplong(text) {
return wrap;
}
-function escape(text) {
- var e = {
- "<": "<",
- ">": ">",
- "'": "'"
- };
- return text.replace(/[<>']/g, function (c) {
- return e[c];
- });
-}
-
function uri(text) {
return URI.withinString(text, function(url, start, end, source) {
if (url.indexOf("javascript:") === 0) {
@@ -48,6 +38,19 @@ function uri(text) {
});
}
+/**
+ * Channels names are strings of length up to fifty (50) characters.
+ * The only restriction on a channel name is that it SHALL NOT contain
+ * any spaces (' '), a control G (^G or ASCII 7), a comma (',').
+ * Channel prefix '&' is handled as '&' because this parser is executed
+ * after entities in the message have been escaped. This prevents a couple of bugs.
+ */
+function channels(text) {
+ return text.replace(
+ /(^|\s|\x07|,)((?:#|&)[^\x07\s\,]{1,49})/g,
+ '$1$2'
+ );
+}
/**
* MIRC compliant colour and style parser
diff --git a/client/js/lounge.js b/client/js/lounge.js
index 413e5b21..b41ef1e1 100644
--- a/client/js/lounge.js
+++ b/client/js/lounge.js
@@ -234,26 +234,6 @@ $(function() {
if (text.find("i").size() === 1) {
text = text.find("i");
}
- // Channels names are strings (beginning with a '&' or '#' character)
- // of length up to 200 characters.
- // See https://tools.ietf.org/html/rfc1459#section-1.3
- text.html(text.html().replace(/(^|\s)([#&][^\x07\x2C\s]{0,199})/ig,
- '$1$2'));
- text.find("span.inline-channel")
- .on("click", function() {
- var chan = $(".network")
- .find(".chan.active")
- .parent(".network")
- .find(".chan[data-title='" + $(this).data("chan") + "']");
- if (chan.size() === 1) {
- chan.click();
- } else {
- socket.emit("input", {
- target: chat.data("id"),
- text: "/join " + $(this).data("chan")
- });
- }
- });
if ((type === "message" || type === "action") && chan.hasClass("channel")) {
var nicks = chan.find(".users").data("nicks");
@@ -529,6 +509,21 @@ $(function() {
});
});
+ chat.on("click", ".inline-channel", function() {
+ var chan = $(".network")
+ .find(".chan.active")
+ .parent(".network")
+ .find(".chan[data-title='" + $(this).data("chan") + "']");
+ if (chan.size() === 1) {
+ chan.click();
+ } else {
+ socket.emit("input", {
+ target: chat.data("id"),
+ text: "/join " + $(this).data("chan")
+ });
+ }
+ });
+
chat.on("click", ".messages", function() {
setTimeout(function() {
var text = "";