diff --git a/src/client.js b/src/client.js index 05fc6916..11de150a 100644 --- a/src/client.js +++ b/src/client.js @@ -144,6 +144,7 @@ Client.prototype.connect = function(args) { ip: args.ip, hostname: args.hostname, }); + network.setNick(nick); client.networks.push(network); client.emit("network", { diff --git a/src/models/network.js b/src/models/network.js index bba9dc66..9e8ce9a8 100644 --- a/src/models/network.js +++ b/src/models/network.js @@ -33,13 +33,34 @@ function Network(attr) { ); } +Network.prototype.setNick = function(nick) { + this.nick = nick; + this.highlightRegex = new RegExp( + // Do not match characters and numbers (unless IRC color) + "(?:^|[^a-z0-9]|\x03[0-9]{1,2})" + + + // Escape nickname, as it may contain regex stuff + nick.replace(/[-\/\\^$*+?.()|[\]{}]/g, "\\$&") + + + // Do not match characters and numbers + "(?:[^a-z0-9]|$)", + + // Case insensitive search + "i" + ); +}; + Network.prototype.toJSON = function() { - var json = _.extend(this, {nick: (this.irc && this.irc.user.nick) || ""}); - return _.omit(json, "irc", "password"); + return _.omit(this, [ + "irc", + "password", + "highlightRegex" + ]); }; Network.prototype.export = function() { var network = _.pick(this, [ + "nick", "name", "host", "port", @@ -51,11 +72,12 @@ Network.prototype.export = function() { "ip", "hostname" ]); - network.nick = (this.irc && this.irc.user.nick) || ""; + network.join = _.map( _.filter(this.channels, {type: "channel"}), "name" ).join(","); + return network; }; diff --git a/src/plugins/irc-events/message.js b/src/plugins/irc-events/message.js index 0689b5a8..65e0bcb1 100644 --- a/src/plugins/irc-events/message.js +++ b/src/plugins/irc-events/message.js @@ -64,9 +64,7 @@ module.exports = function(irc, network) { // Self messages are never highlighted // Non-self messages are highlighted as soon as the nick is detected if (!highlight && !self) { - highlight = data.message.split(" ").some(function(w) { - return (w.replace(/^@/, "").toLowerCase().indexOf(irc.user.nick.toLowerCase()) === 0); - }); + highlight = network.highlightRegex.test(data.message); } if (!self && chan.id !== client.activeChannel) { diff --git a/src/plugins/irc-events/nick.js b/src/plugins/irc-events/nick.js index 35885a97..c84b1b27 100644 --- a/src/plugins/irc-events/nick.js +++ b/src/plugins/irc-events/nick.js @@ -6,6 +6,8 @@ module.exports = function(irc, network) { irc.on("nick", function(data) { var self = false; if (data.nick === irc.user.nick) { + network.setNick(data.new_nick); + var lobby = network.channels[0]; var msg = new Msg({ text: "You're now known as " + data.new_nick, diff --git a/src/plugins/irc-events/welcome.js b/src/plugins/irc-events/welcome.js index 12b0a896..5d86e686 100644 --- a/src/plugins/irc-events/welcome.js +++ b/src/plugins/irc-events/welcome.js @@ -3,7 +3,8 @@ var Msg = require("../../models/msg"); module.exports = function(irc, network) { var client = this; irc.on("registered", function(data) { - network.nick = data.nick; + network.setNick(data.nick); + var lobby = network.channels[0]; var msg = new Msg({ text: "You're now known as " + data.nick diff --git a/test/models/network.js b/test/models/network.js index 000c2cef..f41d0ec4 100644 --- a/test/models/network.js +++ b/test/models/network.js @@ -10,6 +10,7 @@ describe("Network", function() { it("should produce an valid object", function() { var network = new Network({name: "networkName"}); + network.setNick("chillin`"); network.channels.push(new Chan({name: "#thelounge"})); network.channels.push(new Chan({name: "&foobar"})); @@ -22,7 +23,7 @@ describe("Network", function() { username: "", realname: "", commands: [], - nick: "", + nick: "chillin`", join: "#thelounge,&foobar", ip: null, hostname: null diff --git a/test/tests/nickhighlights.js b/test/tests/nickhighlights.js new file mode 100644 index 00000000..9ef9f36b --- /dev/null +++ b/test/tests/nickhighlights.js @@ -0,0 +1,63 @@ +"use strict"; + +var expect = require("chai").expect; + +var Network = require("../../src/models/network"); + +var network = new Network({name: "networkName"}); + +describe("Nickname highlights", function() { + it("should NOT highlight nickname", function() { + network.setNick("lounge-bot"); + + expect("").to.not.match(network.highlightRegex); + expect(" ").to.not.match(network.highlightRegex); + expect("completely unrelated sentence").to.not.match(network.highlightRegex); + expect("foobarlounge-bot").to.not.match(network.highlightRegex); + expect("lounge-botfoobar").to.not.match(network.highlightRegex); + expect("\x03123lounge-bot").to.not.match(network.highlightRegex); + expect("lo\x0312unge-bot").to.not.match(network.highlightRegex); + expect("123lounge-bot").to.not.match(network.highlightRegex); + expect("lounge-botz").to.not.match(network.highlightRegex); + expect("lounge-bot123").to.not.match(network.highlightRegex); + expect("lounge- bot").to.not.match(network.highlightRegex); + expect("lounge_bot").to.not.match(network.highlightRegex); + expect("lounge- bot").to.not.match(network.highlightRegex); + expect("Alounge-bot").to.not.match(network.highlightRegex); + expect("lounge-botW").to.not.match(network.highlightRegex); + }); + + it("should highlight nickname", function() { + network.setNick("lounge-bot"); + + expect("lounge-bot").to.match(network.highlightRegex); + expect("LoUnge-Bot").to.match(network.highlightRegex); + expect("LoUnge-Bot:hello").to.match(network.highlightRegex); + expect("lounge-bot, hello").to.match(network.highlightRegex); + expect("lounge-bot: hello").to.match(network.highlightRegex); + expect("lounge-bot hello").to.match(network.highlightRegex); + expect("\x0312lounge-bot").to.match(network.highlightRegex); + expect("lounge-bot\x0312 test").to.match(network.highlightRegex); + expect("|lounge-bot").to.match(network.highlightRegex); + expect("www.lounge-bot.example.com").to.match(network.highlightRegex); + expect(" lounge-bot").to.match(network.highlightRegex); + expect("@lounge-bot").to.match(network.highlightRegex); + expect("+lounge-bot").to.match(network.highlightRegex); + expect("lounge-bot_, hey").to.match(network.highlightRegex); + expect("lounge-bot-, hey").to.match(network.highlightRegex); + expect("lounge-bot|sleep, hey").to.match(network.highlightRegex); + expect("LOUNGE-bot|sleep, hey").to.match(network.highlightRegex); + }); + + it("changing name should update regex", function() { + network.setNick("lounge-bot"); + + expect("lounge-bot, hello").to.match(network.highlightRegex); + expect("cool_person, hello").to.not.match(network.highlightRegex); + + network.setNick("cool_person"); + + expect("lounge-bot, hello").to.not.match(network.highlightRegex); + expect("cool_person, hello").to.match(network.highlightRegex); + }); +});