0e21a33b1972e16e010e4f2f2a88bdea9c0cf6cb
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
) {
272 anyOpen = function () {
273 return (openTags
.bold
|| openTags
.italic
|| openTags
.underline
|| openTags
.colour
);
275 spanFromOpen = function () {
281 style
+= (openTags
.bold
) ? 'font-weight: bold; ' : '';
282 style
+= (openTags
.italic
) ? 'font-style: italic; ' : '';
283 style
+= (openTags
.underline
) ? 'text-decoration: underline; ' : '';
284 if (openTags
.colour
) {
285 colours
= openTags
.colour
.split(',');
286 style
+= 'color: ' + colours
[0] + ((colours
[1]) ? '; background-color: ' + colours
[1] + ';' : '');
288 return '<span class="formatSpan" style="' + style
+ '">';
291 colourMatch = function (str
) {
292 var re
= /^\x03(([0-9][0-9]?)(,([0-9][0-9]?))?)/;
295 hexFromNum = function (num
) {
296 switch (parseInt(num
, 10)) {
337 for (i
= 0; i
< msg
.length
; i
++) {
341 out
+= currentTag
+ '</span>';
343 openTags
.bold
= !openTags
.bold
;
344 currentTag
= spanFromOpen();
348 out
+= currentTag
+ '</span>';
350 openTags
.italic
= !openTags
.italic
;
351 currentTag
= spanFromOpen();
355 out
+= currentTag
+ '</span>';
357 openTags
.underline
= !openTags
.underline
;
358 currentTag
= spanFromOpen();
362 out
+= currentTag
+ '</span>';
364 match
= colourMatch(msg
.substr(i
, 6));
366 i
+= match
[1].length
;
368 colours
[0] = hexFromNum(match
[2]);
370 colours
[1] = hexFromNum(match
[4]);
372 openTags
.colour
= colours
.join(',');
374 openTags
.colour
= false;
376 currentTag
= spanFromOpen();
380 out
+= currentTag
+ '</span>';
382 openTags
.bold
= openTags
.italic
= openTags
.underline
= openTags
.colour
= false;
386 currentTag
+= msg
[i
];
394 out
+= currentTag
+ '</span>';
402 function formatDate (d
) {
404 return d
.toLocaleDateString() + ', ' + d
.getHours().toString() + ':' + d
.getMinutes().toString() + ':' + d
.getSeconds().toString();
416 Each function in each object is looped through and ran. The resulting text
417 is expected to be returned.
422 onaddmsg: function (event
, opts
) {
427 event
.msg
= event
.msg
.replace(/^((https?\:\/\/|ftp\:\/\/)|(www\.))(\S+)(\w{2,4})(:[0-9]+)?(\/|\/([\w#!:.?+=&%@!\-\/]))?(\.jpg|\.jpeg|\.gif|\.bmp|\.png)$/gi, function (url
) {
428 // Don't let any future plugins change it (ie. html_safe plugins)
429 event
.event_bubbles
= false;
431 var img
= '<img class="link_img_a" src="' + url
+ '" height="100%" width="100%" />';
432 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>';
441 onaddmsg: function (event
, opts
) {
442 event
.msg
= $('<div/>').text(event
.msg
).html();
443 event
.nick
= $('<div/>').text(event
.nick
).html();
451 onaddmsg: function (event
, opts
) {
452 //if (_kiwi.front.cur_channel.name.toLowerCase() !== _kiwi.front.tabviews[event.tabview.toLowerCase()].name) {
453 // _kiwi.front.tabviews[event.tabview].activity();
462 onaddmsg: function (event
, opts
) {
463 //var tab = Tabviews.getTab(event.tabview.toLowerCase());
465 // If we have a highlight...
466 //if (event.msg.toLowerCase().indexOf(_kiwi.gateway.nick.toLowerCase()) > -1) {
467 // if (Tabview.getCurrentTab() !== tab) {
470 // if (_kiwi.front.isChannel(tab.name)) {
471 // event.msg = '<span style="color:red;">' + event.msg + '</span>';
475 // If it's a PM, highlight
476 //if (!_kiwi.front.isChannel(tab.name) && tab.name !== "server"
477 // && Tabview.getCurrentTab().name.toLowerCase() !== tab.name
489 //Following method taken from: http://snipplr.com/view/13533/convert-text-urls-into-links/
490 name
: "linkify_plain",
491 onaddmsg: function (event
, opts
) {
496 event
.msg
= event
.msg
.replace(/((https?\:\/\/|ftp\:\/\/)|(www\.))(\S+)(\w{2,4})(:[0-9]+)?(\/|\/([\w#!:.?+=&%@!\-\/]))?/gi, function (url
) {
498 // If it's any of the supported images in the images plugin, skip it
499 if (url
.match(/(\.jpg|\.jpeg|\.gif|\.bmp|\.png)$/)) {
504 if (url
.match('^https?:\/\/')) {
505 //nice = nice.replace(/^https?:\/\//i,'')
506 nice
= url
; // Shutting up JSLint...
508 url
= 'http://' + url
;
511 //return '<a class="link_ext" target="_blank" rel="nofollow" href="' + url + '">' + nice + '<div class="tt box"></div></a>';
512 return '<a class="link_ext" target="_blank" rel="nofollow" href="' + url
+ '">' + nice
+ '</a>';
521 onaddmsg: function (event
, opts
) {
526 event
.msg
= event
.msg
.replace(/\n/gi, function (txt
) {
536 * Disabled due to many websites closing kiwi with iframe busting
539 oninit: function (event, opts) {
540 $('#windows a.link_ext').live('mouseover', this.mouseover);
541 $('#windows a.link_ext').live('mouseout', this.mouseout);
542 $('#windows a.link_ext').live('click', this.mouseclick);
545 onunload: function (event, opts) {
546 // TODO: make this work (remove all .link_ext_browser as created in mouseover())
547 $('#windows a.link_ext').die('mouseover', this.mouseover);
548 $('#windows a.link_ext').die('mouseout', this.mouseout);
549 $('#windows a.link_ext').die('click', this.mouseclick);
554 mouseover: function (e) {
559 if (tt.text() === '') {
560 tooltip = $('<a class="link_ext_browser">Open in _kiwi..</a>');
564 tt.css('top', -tt.outerHeight() + 'px');
565 tt.css('left', (a.outerWidth() / 2) - (tt.outerWidth() / 2));
568 mouseout: function (e) {
573 mouseclick: function (e) {
577 switch (e.target.className) {
582 case 'link_ext_browser':
583 t = new Utilityview('Browser');
584 t.topic = a.attr('href');
586 t.iframe = $('<iframe border="0" class="utility_view" src="" style="width:100%;height:100%;border:none;"></iframe>');
587 t.iframe.attr('src', a.attr('href'));
588 t.div.append(t.iframe);
600 onaddmsg: function (event
, opts
) {
605 //if (typeof _kiwi.front.tabviews[event.tabview].nick_colours === 'undefined') {
606 // _kiwi.front.tabviews[event.tabview].nick_colours = {};
609 //if (typeof _kiwi.front.tabviews[event.tabview].nick_colours[event.nick] === 'undefined') {
610 // _kiwi.front.tabviews[event.tabview].nick_colours[event.nick] = this.randColour();
613 //var c = _kiwi.front.tabviews[event.tabview].nick_colours[event.nick];
614 var c
= this.randColour();
615 event
.nick
= '<span style="color:' + c
+ ';">' + event
.nick
+ '</span>';
622 randColour: function () {
623 var h
= this.rand(-250, 0),
624 s
= this.rand(30, 100),
625 l
= this.rand(20, 70);
626 return 'hsl(' + h
+ ',' + s
+ '%,' + l
+ '%)';
630 rand: function (min
, max
) {
631 return parseInt(Math
.random() * (max
- min
+ 1), 10) + min
;
637 oninit: function (event
, opts
) {
638 console
.log('registering namespace');
639 $(gateway
).bind("_kiwi.lol.browser", function (e
, data
) {
640 console
.log('YAY kiwitest');
656 * @param {String} data_namespace The namespace for the data store
658 _kiwi
.dataStore = function (data_namespace
) {
659 var namespace = data_namespace
;
661 this.get = function (key
) {
662 return $.jStorage
.get(data_namespace
+ '_' + key
);
665 this.set = function (key
, value
) {
666 return $.jStorage
.set(data_namespace
+ '_' + key
, value
);
670 _kiwi
.data
= new _kiwi
.dataStore('kiwi');
676 * jQuery jStorage plugin
677 * https://github.com/andris9/jStorage/
679 (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
.$);