1 /*jslint devel: true, browser: true, continue: true, sloppy: true, forin: true, plusplus: true, maxerr: 50, indent: 4, nomen: true, regexp: true*/
2 /*globals $, front, gateway, Utilityview */
7 * Suppresses console.log
8 * @param {Boolean} debug Whether to re-enable console.log or not
10 function manageDebug(debug
) {
11 var log
, consoleBackUp
;
13 consoleBackUp
= window
.console
.log
;
14 window
.console
.log = function () {
16 consoleBackUp
.apply(console
, arguments
);
20 log
= window
.opera
? window
.opera
.postError
: alert
;
22 window
.console
.log = function (str
) {
31 * Generate a random string of given length
32 * @param {Number} string_length The length of the random string
33 * @returns {String} The random string
35 function randomString(string_length
) {
36 var chars
= "0123456789ABCDEFGHIJKLMNOPQRSTUVWXTZabcdefghiklmnopqrstuvwxyz",
40 for (i
= 0; i
< string_length
; i
++) {
41 rnum
= Math
.floor(Math
.random() * chars
.length
);
42 randomstring
+= chars
.substring(rnum
, rnum
+ 1);
50 if (typeof String
.prototype.trim
=== 'undefined') {
51 String
.prototype.trim = function () {
52 return this.replace(/^\s+|\s+$/g, "");
58 * @param {Number} length The length of padding
59 * @param {String} characher The character to pad with
60 * @returns {String} The padded string
62 if (typeof String
.prototype.lpad
=== 'undefined') {
63 String
.prototype.lpad = function (length
, character
) {
66 for (i
= 0; i
< length
; i
++) {
69 return (padding
+ this).slice(-length
);
75 * Convert seconds into hours:minutes:seconds
76 * @param {Number} secs The number of seconds to converts
77 * @returns {Object} An object representing the hours/minutes/second conversion of secs
79 function secondsToTime(secs
) {
80 var hours
, minutes
, seconds
, divisor_for_minutes
, divisor_for_seconds
, obj
;
81 hours
= Math
.floor(secs
/ (60 * 60));
83 divisor_for_minutes
= secs
% (60 * 60);
84 minutes
= Math
.floor(divisor_for_minutes
/ 60);
86 divisor_for_seconds
= divisor_for_minutes
% 60;
87 seconds
= Math
.ceil(divisor_for_seconds
);
102 /* Command input Alias + re-writing */
103 function InputPreProcessor () {
104 this.recursive_depth
= 3;
107 this.vars
= {version
: 1};
109 // Current recursive depth
113 // Takes an array of words to process!
114 this.processInput = function (input
) {
115 var words
= input
|| [],
116 alias
= this.aliases
[words
[0]],
118 current_alias_word
= '',
121 // If an alias wasn't found, return the original input
122 if (!alias
) return input
;
124 // Split the alias up into useable words
125 alias
= alias
.split(' ');
126 alias_len
= alias
.length
;
128 // Iterate over each word and pop them into the final compiled array.
129 // Any $ words are processed with the result ending into the compiled array.
130 for (var i
=0; i
<alias_len
; i
++) {
131 current_alias_word
= alias
[i
];
134 if (current_alias_word
[0] !== '$') {
135 compiled
.push(current_alias_word
);
139 // Refering to an input word ($N)
140 if (!isNaN(current_alias_word
[1])) {
141 var num
= current_alias_word
.match(/\$(\d+)(\+)?(\d+)?/);
143 // Did we find anything or does the word it refers to non-existant?
144 if (!num
|| !words
[num
[1]]) continue;
146 if (num
[2] === '+' && num
[3]) {
147 // Add X number of words
148 compiled
= compiled
.concat(words
.slice(parseInt(num
[1], 10), parseInt(num
[1], 10) + parseInt(num
[3], 10)));
149 } else if (num
[2] === '+') {
150 // Add the remaining of the words
151 compiled
= compiled
.concat(words
.slice(parseInt(num
[1], 10)));
154 compiled
.push(words
[parseInt(num
[1], 10)]);
161 // Refering to a variable
162 if (typeof this.vars
[current_alias_word
.substr(1)] !== 'undefined') {
165 compiled
.push(this.vars
[current_alias_word
.substr(1)]);
176 this.process = function (input
) {
179 var words
= input
.split(' ');
182 if (depth
>= this.recursive_depth
) {
187 if (this.aliases
[words
[0]]) {
188 words
= this.processInput(words
);
190 if (this.aliases
[words
[0]]) {
191 words
= this.process(words
.join(' ')).split(' ');
197 return words
.join(' ');
212 * Convert HSL to RGB formatted colour
214 function hsl2rgb(h
, s
, l
) {
220 r
= g
= b
= (l
* 255);
222 function HueToRgb(m1
, m2
, hue
) {
230 v
= m1
+ (m2
- m1
) * hue
* 6;
231 else if (2 * hue
< 1)
233 else if (3 * hue
< 2)
234 v
= m1
+ (m2
- m1
) * (2/3 - hue
) * 6;
246 r
= HueToRgb(m1
, m2
, hue
+ 1/3);
247 g
= HueToRgb(m1
, m2
, hue
);
248 b
= HueToRgb(m1
, m2
, hue
- 1/3);
258 * Formats a message. Adds bold, underline and colouring
259 * @param {String} msg The message to format
260 * @returns {String} The HTML formatted message
262 function formatIRCMsg (msg
) {
265 if ((!msg
) || (typeof msg
!== 'string')) {
270 if (msg
.indexOf(String
.fromCharCode(2)) !== -1) {
272 while (msg
.indexOf(String
.fromCharCode(2)) !== -1) {
273 msg
= msg
.replace(String
.fromCharCode(2), next
);
274 next
= (next
=== '<b>') ? '</b>' : '<b>';
276 if (next
=== '</b>') {
282 if (msg
.indexOf(String
.fromCharCode(31)) !== -1) {
284 while (msg
.indexOf(String
.fromCharCode(31)) !== -1) {
285 msg
= msg
.replace(String
.fromCharCode(31), next
);
286 next
= (next
=== '<u>') ? '</u>' : '<u>';
288 if (next
=== '</u>') {
297 msg
= (function (msg
) {
298 var replace
, colourMatch
, col
, i
, match
, to
, endCol
, fg
, bg
, str
;
303 colourMatch = function (str
) {
304 var re
= /^\x03([0-9][0-5]?)(,([0-9][0-5]?))?/;
310 col = function (num
) {
311 switch (parseInt(num
, 10)) {
348 if (msg
.indexOf('\x03') !== -1) {
349 i
= msg
.indexOf('\x03');
350 replace
= msg
.substr(0, i
);
351 while (i
< msg
.length
) {
355 match
= colourMatch(msg
.substr(i
, 6));
357 //console.log(match);
359 to
= msg
.indexOf('\x03', i
+ 1);
360 endCol
= msg
.indexOf(String
.fromCharCode(15), i
+ 1);
365 to
= ((to
< endCol
) ? to
: endCol
);
371 //console.log(i, to);
374 str
= msg
.substring(i
+ 1 + match
[1].length
+ ((bg
!== null) ? match
[2].length
: 0), to
);
376 replace
+= '<span style="' + ((fg
!== null) ? 'color: ' + fg
+ '; ' : '') + ((bg
!== null) ? 'background-color: ' + bg
+ ';' : '') + '">' + str
+ '</span>';
379 if ((msg
[i
] !== '\x03') && (msg
[i
] !== String
.fromCharCode(15))) {
396 function formatDate (d
) {
398 return d
.toLocaleDateString() + ', ' + d
.getHours().toString() + ':' + d
.getMinutes().toString() + ':' + d
.getSeconds().toString();
410 Each function in each object is looped through and ran. The resulting text
411 is expected to be returned.
416 onaddmsg: function (event
, opts
) {
421 event
.msg
= event
.msg
.replace(/^((https?\:\/\/|ftp\:\/\/)|(www\.))(\S+)(\w{2,4})(:[0-9]+)?(\/|\/([\w#!:.?+=&%@!\-\/]))?(\.jpg|\.jpeg|\.gif|\.bmp|\.png)$/gi, function (url
) {
422 // Don't let any future plugins change it (ie. html_safe plugins)
423 event
.event_bubbles
= false;
425 var img
= '<img class="link_img_a" src="' + url
+ '" height="100%" width="100%" />';
426 return '<a class="link_ext link_img" target="_blank" rel="nofollow" href="' + url
+ '" style="height:50px;width:50px;display:block">' + img
+ '<div class="tt box"></div></a>';
435 onaddmsg: function (event
, opts
) {
436 event
.msg
= $('<div/>').text(event
.msg
).html();
437 event
.nick
= $('<div/>').text(event
.nick
).html();
445 onaddmsg: function (event
, opts
) {
446 //if (_kiwi.front.cur_channel.name.toLowerCase() !== _kiwi.front.tabviews[event.tabview.toLowerCase()].name) {
447 // _kiwi.front.tabviews[event.tabview].activity();
456 onaddmsg: function (event
, opts
) {
457 //var tab = Tabviews.getTab(event.tabview.toLowerCase());
459 // If we have a highlight...
460 //if (event.msg.toLowerCase().indexOf(_kiwi.gateway.nick.toLowerCase()) > -1) {
461 // if (Tabview.getCurrentTab() !== tab) {
464 // if (_kiwi.front.isChannel(tab.name)) {
465 // event.msg = '<span style="color:red;">' + event.msg + '</span>';
469 // If it's a PM, highlight
470 //if (!_kiwi.front.isChannel(tab.name) && tab.name !== "server"
471 // && Tabview.getCurrentTab().name.toLowerCase() !== tab.name
483 //Following method taken from: http://snipplr.com/view/13533/convert-text-urls-into-links/
484 name
: "linkify_plain",
485 onaddmsg: function (event
, opts
) {
490 event
.msg
= event
.msg
.replace(/((https?\:\/\/|ftp\:\/\/)|(www\.))(\S+)(\w{2,4})(:[0-9]+)?(\/|\/([\w#!:.?+=&%@!\-\/]))?/gi, function (url
) {
492 // If it's any of the supported images in the images plugin, skip it
493 if (url
.match(/(\.jpg|\.jpeg|\.gif|\.bmp|\.png)$/)) {
498 if (url
.match('^https?:\/\/')) {
499 //nice = nice.replace(/^https?:\/\//i,'')
500 nice
= url
; // Shutting up JSLint...
502 url
= 'http://' + url
;
505 //return '<a class="link_ext" target="_blank" rel="nofollow" href="' + url + '">' + nice + '<div class="tt box"></div></a>';
506 return '<a class="link_ext" target="_blank" rel="nofollow" href="' + url
+ '">' + nice
+ '</a>';
515 onaddmsg: function (event
, opts
) {
520 event
.msg
= event
.msg
.replace(/\n/gi, function (txt
) {
530 * Disabled due to many websites closing kiwi with iframe busting
533 oninit: function (event, opts) {
534 $('#windows a.link_ext').live('mouseover', this.mouseover);
535 $('#windows a.link_ext').live('mouseout', this.mouseout);
536 $('#windows a.link_ext').live('click', this.mouseclick);
539 onunload: function (event, opts) {
540 // TODO: make this work (remove all .link_ext_browser as created in mouseover())
541 $('#windows a.link_ext').die('mouseover', this.mouseover);
542 $('#windows a.link_ext').die('mouseout', this.mouseout);
543 $('#windows a.link_ext').die('click', this.mouseclick);
548 mouseover: function (e) {
553 if (tt.text() === '') {
554 tooltip = $('<a class="link_ext_browser">Open in _kiwi..</a>');
558 tt.css('top', -tt.outerHeight() + 'px');
559 tt.css('left', (a.outerWidth() / 2) - (tt.outerWidth() / 2));
562 mouseout: function (e) {
567 mouseclick: function (e) {
571 switch (e.target.className) {
576 case 'link_ext_browser':
577 t = new Utilityview('Browser');
578 t.topic = a.attr('href');
580 t.iframe = $('<iframe border="0" class="utility_view" src="" style="width:100%;height:100%;border:none;"></iframe>');
581 t.iframe.attr('src', a.attr('href'));
582 t.div.append(t.iframe);
594 onaddmsg: function (event
, opts
) {
599 //if (typeof _kiwi.front.tabviews[event.tabview].nick_colours === 'undefined') {
600 // _kiwi.front.tabviews[event.tabview].nick_colours = {};
603 //if (typeof _kiwi.front.tabviews[event.tabview].nick_colours[event.nick] === 'undefined') {
604 // _kiwi.front.tabviews[event.tabview].nick_colours[event.nick] = this.randColour();
607 //var c = _kiwi.front.tabviews[event.tabview].nick_colours[event.nick];
608 var c
= this.randColour();
609 event
.nick
= '<span style="color:' + c
+ ';">' + event
.nick
+ '</span>';
616 randColour: function () {
617 var h
= this.rand(-250, 0),
618 s
= this.rand(30, 100),
619 l
= this.rand(20, 70);
620 return 'hsl(' + h
+ ',' + s
+ '%,' + l
+ '%)';
624 rand: function (min
, max
) {
625 return parseInt(Math
.random() * (max
- min
+ 1), 10) + min
;
631 oninit: function (event
, opts
) {
632 console
.log('registering namespace');
633 $(gateway
).bind("_kiwi.lol.browser", function (e
, data
) {
634 console
.log('YAY kiwitest');
650 * @param {String} data_namespace The namespace for the data store
652 _kiwi
.dataStore = function (data_namespace
) {
653 var namespace = data_namespace
;
655 this.get = function (key
) {
656 return $.jStorage
.get(data_namespace
+ '_' + key
);
659 this.set = function (key
, value
) {
660 return $.jStorage
.set(data_namespace
+ '_' + key
, value
);
664 _kiwi
.data
= new _kiwi
.dataStore('kiwi');
670 * jQuery jStorage plugin
671 * https://github.com/andris9/jStorage/
673 (function(f
){if(!f
||!(f
.toJSON
||Object
.toJSON
||window
.JSON
)){throw new Error("jQuery, MooTools or Prototype needs to be loaded before jStorage!")}var g
={},d
={jStorage
:"{}"},h
=null,j
=0,l
=f
.toJSON
||Object
.toJSON
||(window
.JSON
&&(JSON
.encode
||JSON
.stringify
)),e
=f
.evalJSON
||(window
.JSON
&&(JSON
.decode
||JSON
.parse
))||function(m
){return String(m
).evalJSON()},i
=false;_XMLService
={isXML:function(n
){var m
=(n
?n
.ownerDocument
||n
:0).documentElement
;return m
?m
.nodeName
!=="HTML":false},encode:function(n
){if(!this.isXML(n
)){return false}try{return new XMLSerializer().serializeToString(n
)}catch(m
){try{return n
.xml
}catch(o
){}}return false},decode:function(n
){var m
=("DOMParser" in window
&&(new DOMParser()).parseFromString
)||(window
.ActiveXObject
&&function(p
){var q
=new ActiveXObject("Microsoft.XMLDOM");q
.async
="false";q
.loadXML(p
);return q
}),o
;if(!m
){return false}o
=m
.call("DOMParser" in window
&&(new DOMParser())||window
,n
,"text/xml");return this.isXML(o
)?o
:false}};function k(){if("localStorage" in window
){try{if(window
.localStorage
){d
=window
.localStorage
;i
="localStorage"}}catch(p
){}}else{if("globalStorage" in window
){try{if(window
.globalStorage
){d
=window
.globalStorage
[window
.location
.hostname
];i
="globalStorage"}}catch(o
){}}else{h
=document
.createElement("link");if(h
.addBehavior
){h
.style
.behavior
="url(#default#userData)";document
.getElementsByTagName("head")[0].appendChild(h
);h
.load("jStorage");var n
="{}";try{n
=h
.getAttribute("jStorage")}catch(m
){}d
.jStorage
=n
;i
="userDataBehavior"}else{h
=null;return}}}b()}function b(){if(d
.jStorage
){try{g
=e(String(d
.jStorage
))}catch(m
){d
.jStorage
="{}"}}else{d
.jStorage
="{}"}j
=d
.jStorage
?String(d
.jStorage
).length
:0}function c(){try{d
.jStorage
=l(g
);if(h
){h
.setAttribute("jStorage",d
.jStorage
);h
.save("jStorage")}j
=d
.jStorage
?String(d
.jStorage
).length
:0}catch(m
){}}function a(m
){if(!m
||(typeof m
!="string"&&typeof m
!="number")){throw new TypeError("Key name must be string or numeric")}return true}f
.jStorage
={version
:"0.1.5.1",set:function(m
,n
){a(m
);if(_XMLService
.isXML(n
)){n
={_is_xml
:true,xml
:_XMLService
.encode(n
)}}g
[m
]=n
;c();return n
},get:function(m
,n
){a(m
);if(m
in g
){if(g
[m
]&&typeof g
[m
]=="object"&&g
[m
]._is_xml
&&g
[m
]._is_xml
){return _XMLService
.decode(g
[m
].xml
)}else{return g
[m
]}}return typeof(n
)=="undefined"?null:n
},deleteKey:function(m
){a(m
);if(m
in g
){delete g
[m
];c();return true}return false},flush:function(){g
={};c();return true},storageObj:function(){function m(){}m
.prototype=g
;return new m()},index:function(){var m
=[],n
;for(n
in g
){if(g
.hasOwnProperty(n
)){m
.push(n
)}}return m
},storageSize:function(){return j
},currentBackend:function(){return i
},storageAvailable:function(){return !!i
},reInit:function(){var m
,o
;if(h
&&h
.addBehavior
){m
=document
.createElement("link");h
.parentNode
.replaceChild(m
,h
);h
=m
;h
.style
.behavior
="url(#default#userData)";document
.getElementsByTagName("head")[0].appendChild(h
);h
.load("jStorage");o
="{}";try{o
=h
.getAttribute("jStorage")}catch(n
){}d
.jStorage
=o
;i
="userDataBehavior"}b()}};k()})(window
.jQuery
||window
.$);