From ca7e63eabacd9c1b7eccd2d048a61a02c6847954 Mon Sep 17 00:00:00 2001 From: Darren Date: Sat, 27 Aug 2011 20:02:40 +0100 Subject: [PATCH] Client plugin system revamped to match server side plugins --- css/default.css | 2 + js/front.js | 49 ++++++---------- js/util.js | 152 ++++++++++++++++++++++++++++++++++-------------- 3 files changed, 128 insertions(+), 75 deletions(-) diff --git a/css/default.css b/css/default.css index 184cf36..b0bc56b 100644 --- a/css/default.css +++ b/css/default.css @@ -189,6 +189,8 @@ body, html { #kiwi .messages a:hover .tt a { cursor:pointer; color:inherit; } #kiwi .messages a:active .tt a { color:inherit; } +#kiwi .messages a.link_img { border: 1px solid gray; } + diff --git a/js/front.js b/js/front.js index 5e7f328..35ecd0a 100644 --- a/js/front.js +++ b/js/front.js @@ -1088,6 +1088,7 @@ var Utilityview = function (name, src) { var tmp_tabname = 'kiwi_tab_' + name; this.name = name; + this.topic = src; if (!front.tabviewExists(name)) { $('#kiwi .windows .scroller').append('
'); @@ -1099,7 +1100,7 @@ var Utilityview = function (name, src) { this.tab = $('#' + tmp_tabname); - this.iframe = $(''); + this.iframe = $(''); if(src) this.iframe.attr('src', src); this.div.append(this.iframe); @@ -1110,6 +1111,7 @@ Utilityview.prototype.name = null; Utilityview.prototype.div = null; Utilityview.prototype.tab = null; Utilityview.prototype.iframe = null; +Utilityview.prototype.topic = ' '; Utilityview.prototype.show = function () { $('#kiwi .messages').removeClass("active"); $('#kiwi .userlist ul').removeClass("active"); @@ -1123,7 +1125,7 @@ Utilityview.prototype.show = function () { this.addPartImage(); - front.setTopicText(' '); + front.setTopicText(this.topic); front.cur_channel = this; // If we're using fancy scrolling, refresh it @@ -1252,35 +1254,19 @@ Tabview.prototype.clearPartImage = function () { }; Tabview.prototype.addMsg = function (time, nick, msg, type, style) { - var html_nick, self, tmp, plugin_ret, i, d, re, line_msg; - html_nick = $('
').text(nick).html(); + var self, tmp, plugin_ret, i, d, re, line_msg; self = this; - tmp = msg; - plugin_ret = ''; - for (i in plugins.privmsg) { - if ((plugins.privmsg[i].onprivmsg instanceof Function)) { - plugin_ret = ''; - try { - plugin_ret = plugins.privmsg[i].onprivmsg(tmp, this.name); - - // If this plugin has returned false, do not add this message - if (plugin_ret === false) { - return; - } - } catch (e) { - } - - // If we actually have a string from the plugin, use it - if (typeof plugin_ret === "string") { - tmp = plugin_ret; - } - } - } - msg = tmp; + tmp = {msg: msg, time: time, nick: nick, tabview: this.name}; + tmp = plugs.run('addmsg', tmp); + if (!tmp) return; - //var html_msg = $('
').text(msg).html()+' '; // Add the space so the styling always has at least 1 character to go from + + msg = tmp.msg; + time = tmp.time; + nick = tmp.nick; + if (time === null) { d = new Date(); time = d.getHours().toString().lpad(2, "0") + ":" + d.getMinutes().toString().lpad(2, "0") + ":" + d.getSeconds().toString().lpad(2, "0"); @@ -1326,15 +1312,14 @@ Tabview.prototype.addMsg = function (time, nick, msg, type, style) { } } + // Make the channels clickable re = new RegExp('\\B(' + gateway.channel_prefix + '[^ ,.\\007]+)', 'g'); - msg = msg.replace(re, function (match) { - return '' + match + ''; + return '' + match + ''; }); - line_msg = $('
' + time + '
' + html_nick + '
' + msg + '
'); - //$('a.link_ext', line_msg).tooltip({ tip : $('#tooltip_link'), effect : 'toggle', offset : [2, 0] }); - + // Build up and add the line + line_msg = $('
' + time + '
' + nick + '
' + msg + '
'); this.div.append(line_msg); if (!touchscreen) { diff --git a/js/util.js b/js/util.js index a0906e7..ff6c4a0 100644 --- a/js/util.js +++ b/js/util.js @@ -45,94 +45,104 @@ String.prototype.lpad = function(length, character){ Each function in each object is looped through and ran. The resulting text is expected to be returned. */ -var plugins={}; -plugins.privmsg = [ +var plugins = [ + { + name: "images", + onaddmsg: function(event, opts){ + if( !event.msg ) return event; + + event.msg = event.msg.replace(/^((https?\:\/\/|ftp\:\/\/)|(www\.))(\S+)(\w{2,4})(:[0-9]+)?(\/|\/([\w#!:.?+=&%@!\-\/]))?(\.jpg|\.jpeg|\.gif|\.bmp|\.png)$/gi,function(url){ + // Don't let any future plugins change it (ie. html_safe plugins) + event.event_bubbles = false; + + var img = ''; + return ''+ img +'
'; + }); + + return event; + } + }, + { name: "html_safe", - onprivmsg: function(inp, tabview){ - return $('
').text(inp).html(); + onaddmsg: function(event, opts){ + event.msg = $('
').text(event.msg).html(); + event.nick = $('
').text(event.nick).html(); + + return event; } }, - + { name: "activity", - onprivmsg: function(inp, tabview){ - if(front.cur_channel.name.toLowerCase() != front.tabviews[tabview.toLowerCase()].name){ - front.tabviews[tabview].activity(); + onaddmsg: function(event, opts){ + if(front.cur_channel.name.toLowerCase() != front.tabviews[event.tabview.toLowerCase()].name){ + front.tabviews[event.tabview].activity(); } + + return event; } }, { name: "highlight", - onprivmsg: function(inp, tabview){ - if(inp.toLowerCase().indexOf(gateway.nick.toLowerCase()) > -1){ - if(front.cur_channel.name.toLowerCase() != front.tabviews[tabview.toLowerCase()].name){ - front.tabviews[tabview].highlight(); + onaddmsg: function(event, opts){ + if(event.msg.toLowerCase().indexOf(gateway.nick.toLowerCase()) > -1){ + if(front.cur_channel.name.toLowerCase() != front.tabviews[event.tabview.toLowerCase()].name){ + front.tabviews[event.tabview].highlight(); + } + if(front.isChannel(front.tabviews[event.tabview].name)){ + event.msg = ''+event.msg+''; } - if(front.isChannel(front.tabviews[tabview].name)) - inp = ''+inp+''; } if( - !front.isChannel(front.tabviews[tabview].name) && front.tabviews[tabview].name != "server" - && front.cur_channel.name.toLowerCase() != front.tabviews[tabview.toLowerCase()].name + !front.isChannel(front.tabviews[event.tabview].name) && front.tabviews[event.tabview].name != "server" + && front.cur_channel.name.toLowerCase() != front.tabviews[event.tabview.toLowerCase()].name ){ - front.tabviews[tabview].highlight(); + front.tabviews[event.tabview].highlight(); } - return inp; - } - }, - /* - { - name: "images", - onprivmsg: function(text){ - if( !text ) return text; - //alert("-"+text+"-"); - text = text.replace(/^((https?\:\/\/|ftp\:\/\/)|(www\.))(\S+)(\w{2,4})(:[0-9]+)?(\/|\/([\w#!:.?+=&%@!\-\/]))?(\.jpg|\.jpeg|\.gif|\.bmp|\.png)$/gi,function(url){ - var img = ''; - return ''+ img +''; - }); - - return text; + return event; } - }, + }, - */ { //Following method taken from: http://snipplr.com/view/13533/convert-text-urls-into-links/ name: "linkify_plain", - onprivmsg: function(text){ - if( !text ) return text; + onaddmsg: function(event, opts){ + if( !event.msg ) return event; - text = text.replace(/((https?\:\/\/|ftp\:\/\/)|(www\.))(\S+)(\w{2,4})(:[0-9]+)?(\/|\/([\w#!:.?+=&%@!\-\/]))?/gi,function(url){ + event.msg = event.msg.replace(/((https?\:\/\/|ftp\:\/\/)|(www\.))(\S+)(\w{2,4})(:[0-9]+)?(\/|\/([\w#!:.?+=&%@!\-\/]))?/gi,function(url){ + // If it's any of the supported images in the images plugin, skip it + if(url.match('(\.jpg|\.jpeg|\.gif|\.bmp|\.png)$')) return url; + nice = url; if(url.match('^https?:\/\/')){ //nice = nice.replace(/^https?:\/\//i,'') - }else{ + } else { url = 'http://'+url; } return ''+ nice +'
'; }); - return text; + return event; } }, { name: "lftobr", - onprivmsg: function(text){ - if( !text ) return text; + onaddmsg: function(event, opts){ + if( !event.msg ) return event; - text = text.replace(/\n/gi,function(txt){ + event.msg = event.msg.replace(/\n/gi,function(txt){ return '
'; }); - return text; + return event; } } ]; @@ -145,6 +155,62 @@ plugins.privmsg = [ +plugs = {}; +plugs.loaded = {}; +plugs.loadPlugin = function (plugin) { + if (typeof plugin.name !== 'string') return false; + + var plugin_ret = plugs.run('plugin_load', {plugin: plugin}); + if (typeof plugin_ret === 'object') plugs.loaded[plugin_ret.plugin.name] = plugin_ret.plugin; + plugs.run('init', {}, {run_only: plugin_ret.plugin.name}); + + return true; +}; + + + +/* + * Run an event against all loaded plugins + */ +plugs.run = function (event_name, event_data, opts) { + var ret = event_data, + ret_tmp, plugin_name; + + // Set some defaults if not provided + event_data = (typeof event_data === 'undefined') ? {} : event_data; + opts = (typeof opts === 'undefined') ? {} : opts; + + for (plugin_name in plugs.loaded) { + // If we're only calling 1 plugin, make sure it's that one + if (typeof opts.run_only === 'string' && opts.run_only !== plugin_name) continue; + + if (typeof plugs.loaded[plugin_name]['on' + event_name] === 'function') { + try { + ret_tmp = plugs.loaded[plugin_name]['on' + event_name](ret, opts); + if (ret_tmp === null) { + return null; + } + ret = ret_tmp; + + if (typeof ret.event_bubbles === 'boolean' && ret.event_bubbles === false){ + delete ret.event_bubbles; + return ret; + } + } catch (e) { + } + } + } + + return ret; +}; + + +for(var i in plugins) plugs.loadPlugin(plugins[i]); + + + + + -- 2.25.1