1 /*jslint nomen: true, devel: true, undef: true, browser: true, continue: true, sloppy: true, forin: true, newcap: true, plusplus: true, maxerr: 50, indent: 4 */
2 /*global gateway, io, $, iScroll, agent, touchscreen, init_data, plugs, plugins, registerTouches, randomString */
20 /*global Box, touch_scroll:true */
21 var about_info
, supportsOrientationChange
, orientationEvent
, scroll_opts
;
22 kiwi
.gateway
.nick
= 'kiwi_' + Math
.ceil(100 * Math
.random()) + Math
.ceil(100 * Math
.random());
23 kiwi
.gateway
.session_id
= null;
25 $(kiwi
.gateway
).bind("onmsg", kiwi
.front
.onMsg
);
26 $(kiwi
.gateway
).bind("onnotice", kiwi
.front
.onNotice
);
27 $(kiwi
.gateway
).bind("onaction", kiwi
.front
.onAction
);
28 $(kiwi
.gateway
).bind("onmotd", kiwi
.front
.onMOTD
);
29 $(kiwi
.gateway
).bind("onoptions", kiwi
.front
.onOptions
);
30 $(kiwi
.gateway
).bind("onconnect", kiwi
.front
.onConnect
);
31 $(kiwi
.gateway
).bind("onconnect_fail", kiwi
.front
.onConnectFail
);
32 $(kiwi
.gateway
).bind("ondisconnect", kiwi
.front
.onDisconnect
);
33 $(kiwi
.gateway
).bind("onnick", kiwi
.front
.onNick
);
34 $(kiwi
.gateway
).bind("onuserlist", kiwi
.front
.onUserList
);
35 $(kiwi
.gateway
).bind("onuserlist_end", kiwi
.front
.onUserListEnd
);
36 $(kiwi
.gateway
).bind("onlist_start", kiwi
.front
.onChannelListStart
);
37 $(kiwi
.gateway
).bind("onlist_channel", kiwi
.front
.onChannelList
);
38 $(kiwi
.gateway
).bind("onlist_end", kiwi
.front
.onChannelListEnd
);
39 $(kiwi
.gateway
).bind("onjoin", kiwi
.front
.onJoin
);
40 $(kiwi
.gateway
).bind("ontopic", kiwi
.front
.onTopic
);
41 $(kiwi
.gateway
).bind("onpart", kiwi
.front
.onPart
);
42 $(kiwi
.gateway
).bind("onkick", kiwi
.front
.onKick
);
43 $(kiwi
.gateway
).bind("onquit", kiwi
.front
.onQuit
);
44 $(kiwi
.gateway
).bind("onmode", kiwi
.front
.onMode
);
45 $(kiwi
.gateway
).bind("onwhois", kiwi
.front
.onWhois
);
46 $(kiwi
.gateway
).bind("onsync", kiwi
.front
.onSync
);
47 $(kiwi
.gateway
).bind("onchannel_redirect", kiwi
.front
.onChannelRedirect
);
48 $(kiwi
.gateway
).bind("ondebug", kiwi
.front
.onDebug
);
49 $(kiwi
.gateway
).bind("onctcp_request", kiwi
.front
.onCTCPRequest
);
50 $(kiwi
.gateway
).bind("onctcp_response", kiwi
.front
.onCTCPResponse
);
51 $(kiwi
.gateway
).bind("onirc_error", kiwi
.front
.onIRCError
);
52 $(kiwi
.gateway
).bind("onkiwi", kiwi
.front
.onKiwi
);
56 // Build the about box
57 kiwi
.front
.boxes
.about
= new Box("about");
58 about_info
= 'UI adapted for ' + agent
;
60 about_info
+= ' touchscreen ';
62 about_info
+= 'usage';
63 $('#tmpl_about_box').tmpl({
65 front_revision
: kiwi
.front
.revision
,
66 gateway_revision
: kiwi
.gateway
.revision
67 }).appendTo(kiwi
.front
.boxes
.about
.content
);
69 //$(window).bind("beforeunload", function(){ kiwi.gateway.quit(); });
72 $('#kiwi').addClass('touchscreen');
74 // Single touch scrolling through scrollback for touchscreens
76 touch_scroll
= new iScroll('windows', scroll_opts
);
79 kiwi
.front
.registerKeys();
81 $('#kiwi .toolbars').resize(kiwi
.front
.doLayoutSize
);
82 $(window
).resize(kiwi
.front
.doLayoutSize
);
84 // Add the resizer for the userlist
85 $('<div id="nicklist_resize" style="position:absolute; cursor:w-resize; width:5px;"></div>').appendTo('#kiwi');
86 $('#nicklist_resize').draggable({axis
: "x", drag: function () {
88 new_width
= $(document
).width() - parseInt(t
.css('left'), 10);
90 new_width
= new_width
- parseInt($('#kiwi .userlist').css('margin-left'), 10);
91 new_width
= new_width
- parseInt($('#kiwi .userlist').css('margin-right'), 10);
93 // Make sure we don't remove the userlist alltogether
94 console
.log(new_width
);
96 $(this).data('draggable').offset
.click
.left
= 10;
100 kiwi
.front
.cur_channel
.setUserlistWidth(new_width
);
104 $('#kiwi .formconnectwindow').submit(function () {
105 var netsel
= $('#kiwi .formconnectwindow .network'),
106 netport
= $('#kiwi .formconnectwindow .port'),
107 netssl
= $('#kiwi .formconnectwindow .ssl'),
108 nick
= $('#kiwi .formconnectwindow .nick'),
111 if (nick
.val() === '') {
112 nick
.val('Nick please!');
117 tmp
= nick
.val().split(' ');
118 kiwi
.gateway
.nick
= tmp
[0];
120 init_data
.channel
= $('#channel').val();
122 kiwi
.front
.doLayout();
124 kiwi
.front
.run('/connect ' + netsel
.val() + ' ' + netport
.val() + ' ' + (netssl
.attr('checked') ? 'true' : ''));
127 $('#kiwi .connectwindow').slideUp('', kiwi
.front
.barsShow
);
128 $('#windows').click(function () { $('#kiwi_msginput').focus(); });
133 supportsOrientationChange
= (typeof window
.onorientationchange
!== undefined);
134 orientationEvent
= supportsOrientationChange
? "orientationchange" : "resize";
135 if (window
.addEventListener
) {
136 window
.addEventListener(orientationEvent
, kiwi
.front
.doLayoutSize
, false);
139 window
.attachEvent(orientationEvent
, kiwi
.front
.doLayoutSize
, false);
141 //$('#kiwi').bind("resize", kiwi.front.doLayoutSize, false);
143 kiwi
.front
.doLayout();
144 kiwi
.front
.barsHide();
146 kiwi
.front
.tabviewAdd('server');
147 kiwi
.front
.tabviews
.server
.userlist_width
= 0; // Disable the userlist
149 // Any pre-defined nick?
150 if (typeof window
.init_data
.nick
=== "string") {
151 $('#kiwi .formconnectwindow .nick').val(init_data
.nick
);
154 // Any pre-defined channels?
155 if (typeof window
.init_data
.channel
=== 'string') {
156 $('#channel').val(init_data
.channel
);
159 // Fix for Opera inserting a spurious <br/>
160 $('#kiwi .cur_topic br').remove();
162 $('#kiwi .cur_topic').keydown(function (e
) {
163 if (e
.which
=== 13) {
167 $('#kiwi_msginput').focus();
168 } else if (e
.which
=== 27) {
171 $(this).text(kiwi
.front
.original_topic
);
172 $('#kiwi_msginput').focus();
175 /*$('.cur_topic').live('keypress', function(e) {
176 if (e.keyCode === 13) {
180 $('#kiwi_msginput').focus();
181 } else if (e.keyCode === 27) {
184 $(this).text(kiwi.front.original_topic);
187 $('.cur_topic').live('change', function () {
189 text
= $(this).text();
190 if (text
!== kiwi
.front
.original_topic
) {
191 chan
= kiwi
.front
.cur_channel
.name
;
192 kiwi
.gateway
.setTopic(chan
, text
);
197 $('#windows a.chan').live('click', function () {
198 kiwi
.front
.joinChannel($(this).text());
202 kiwi
.data
.set('chanList', []);
207 kiwi
.plugs
.loadPlugin(plugins
[i
]);
212 doLayoutSize: function () {
213 var kiwi
, toolbars
, ul
, n_top
, n_bottom
, nl
;
216 if (kiwi
.width() < 330 && !kiwi
.hasClass('small_kiwi')) {
217 console
.log("switching to small kiwi");
218 kiwi
.removeClass('large_kiwi');
219 kiwi
.addClass('small_kiwi');
220 } else if (kiwi
.width() >= 330 && !kiwi
.hasClass('large_kiwi')) {
221 kiwi
.removeClass('small_kiwi');
222 kiwi
.addClass('large_kiwi');
225 toolbars
= $('#kiwi .cur_topic');
226 ul
= $('#kiwi .userlist');
228 n_top
= parseInt(toolbars
.offset().top
, 10) + parseInt(toolbars
.outerHeight(true), 10);
229 n_bottom
= $(document
).height() - parseInt($('#kiwi .control').offset().top
, 10);
231 $('#kiwi .windows').css({top
: n_top
+ 'px', bottom
: n_bottom
+ 'px'});
232 ul
.css({top
: n_top
+ 'px', bottom
: n_bottom
+ 'px'});
234 nl
= $('#nicklist_resize');
235 nl
.css({top
: n_top
+ 'px', bottom
: n_bottom
+ 'px', left
: $(document
).width() - ul
.outerWidth(true)});
239 doLayout: function () {
240 $('#kiwi .msginput .nick a').text(kiwi
.gateway
.nick
);
241 $('#kiwi_msginput').val(' ');
242 $('#kiwi_msginput').focus();
246 joinChannel: function (chan_name
) {
247 var chans
= chan_name
.split(','),
252 if (kiwi
.front
.tabviews
[chan
.toLowerCase()] === undefined || (kiwi
.front
.tabviews
[chan
.toLowerCase()] !== undefined && kiwi
.front
.tabviews
[chan
.toLowerCase()].safe_to_close
=== true)) {
253 kiwi
.gateway
.join(chan
);
254 kiwi
.front
.tabviewAdd(chan
);
256 kiwi
.front
.tabviews
[chan
.toLowerCase()].show();
262 run: function (msg
) {
263 var parts
, dest
, t
, pos
, textRange
, d
, plugin_event
, msg_sliced
;
265 // Run through any plugins
266 plugin_event
= {command
: msg
};
267 plugin_event
= kiwi
.plugs
.run('command_run', plugin_event
);
268 if (!plugin_event
|| typeof plugin_event
.command
=== 'undefined') {
272 // Update msg if it's been changed by any plugins
273 msg
= plugin_event
.command
.toString();
275 console
.log("running " + msg
);
276 if (msg
.substring(0, 1) === '/') {
277 parts
= msg
.split(' ');
278 switch (parts
[0].toLowerCase()) {
281 kiwi
.front
.joinChannel(parts
[1]);
286 if (parts
[1] === undefined) {
287 alert('Usage: /connect servername [[port] [ssl]]');
291 if (parts
[2] === undefined) {
295 if ((parts
[3] === undefined) || (parts
[3] === 'false') || (parts
[3] === 'no')) {
301 kiwi
.front
.cur_channel
.addMsg(null, ' ', '=== Connecting to ' + parts
[1] + ' on port ' + parts
[2] + ((parts
[3]) ? ' using SSL' : '') + '...', 'status');
302 kiwi
.gateway
.connect(parts
[1], parts
[2], parts
[3]);
306 console
.log("/nick");
307 if (parts
[1] === undefined) {
308 console
.log("calling show nick");
309 kiwi
.front
.showChangeNick();
311 console
.log("sending raw");
312 kiwi
.gateway
.raw(msg
.substring(1));
317 if (typeof parts
[1] === "undefined") {
318 if (kiwi
.front
.cur_channel
.safe_to_close
) {
319 kiwi
.front
.cur_channel
.close();
321 kiwi
.gateway
.raw(msg
.substring(1) + ' ' + kiwi
.front
.cur_channel
.name
);
324 kiwi
.gateway
.raw(msg
.substring(1));
329 if (typeof parts
[1] !== "undefined") {
330 kiwi
.gateway
.raw(msg
.substring(1));
335 kiwi
.gateway
.debug();
340 if (typeof parts
[1] !== "undefined") {
341 kiwi
.front
.tabviewAdd(parts
[1]);
348 if (typeof parts
[1] !== "undefined") {
349 msg_sliced
= msg
.split(' ').slice(2).join(' ');
350 kiwi
.gateway
.msg(parts
[1], msg_sliced
);
352 if (!kiwi
.front
.tabviewExists(parts
[1])) {
353 kiwi
.front
.tabviewAdd(parts
[1]);
355 kiwi
.front
.tabviews
[parts
[1].toLowerCase()].addMsg(null, kiwi
.gateway
.nick
, msg_sliced
);
361 if (typeof parts
[1] === 'undefined') {
364 kiwi
.gateway
.raw('KICK ' + kiwi
.front
.cur_channel
.name
+ ' ' + msg
.split(' ', 2)[1]);
368 kiwi
.gateway
.raw(msg
.replace(/^\/quote /i, ''));
372 kiwi
.gateway
.action(kiwi
.front
.cur_channel
.name
, msg
.substring(4));
373 //kiwi.front.tabviews[destination.toLowerCase()].addMsg(null, ' ', '* '+data.nick+' '+data.msg, 'color:green;');
374 kiwi
.front
.cur_channel
.addMsg(null, ' ', '* ' + kiwi
.gateway
.nick
+ ' ' + msg
.substring(4), 'action', 'color:#555;');
379 msg
= parts
.slice(2).join(' ');
381 kiwi
.gateway
.notice(dest
, msg
);
382 this.onNotice({}, {nick
: kiwi
.gateway
.nick
, channel
: dest
, msg
: msg
});
386 if (parts
[1] !== undefined) {
387 kiwi
.front
.windowsShow(parseInt(parts
[1], 10));
392 kiwi
.gateway
.quit(parts
.slice(1).join(' '));
396 if (parts
[1] === undefined) {
398 if (t
.createTextRange
) {
399 pos
= t
.text().length();
400 textRange
= t
.createTextRange();
401 textRange
.collapse(true);
402 textRange
.moveEnd(pos
);
403 textRange
.moveStart(pos
);
405 } else if (t
.setSelectionRange
) {
406 t
.setSelectionRange(pos
, pos
);
409 kiwi
.gateway
.setTopic(kiwi
.front
.cur_channel
.name
, msg
.split(' ', 2)[1]);
410 //kiwi.gateway.raw('TOPIC ' + kiwi.front.cur_channel.name + ' :' + msg.split(' ', 2)[1]);
415 kiwi
.gateway
.kiwi(kiwi
.front
.cur_channel
.name
, msg
.substring(6));
419 //kiwi.front.cur_channel.addMsg(null, ' ', '--> Invalid command: '+parts[0].substring(1));
420 kiwi
.gateway
.raw(msg
.substring(1));
424 //alert('Sending message: '+msg);
425 if (msg
.trim() === '') {
428 if (kiwi
.front
.cur_channel
.name
!== 'server') {
429 kiwi
.gateway
.msg(kiwi
.front
.cur_channel
.name
, msg
);
431 d
= d
.getHours() + ":" + d
.getMinutes();
432 //kiwi.front.addMsg(d, kiwi.gateway.nick, msg);
433 kiwi
.front
.cur_channel
.addMsg(null, kiwi
.gateway
.nick
, msg
);
439 onMsg: function (e
, data
) {
440 var destination
, plugin_event
;
441 // Is this message from a user?
442 if (data
.channel
=== kiwi
.gateway
.nick
) {
443 destination
= data
.nick
.toLowerCase();
445 destination
= data
.channel
.toLowerCase();
448 plugin_event
= {nick
: data
.nick
, msg
: data
.msg
, destination
: destination
};
449 plugin_event
= kiwi
.plugs
.run('msg_recieved', plugin_event
);
454 if (!kiwi
.front
.tabviewExists(plugin_event
.destination
)) {
455 kiwi
.front
.tabviewAdd(plugin_event
.destination
);
457 kiwi
.front
.tabviews
[plugin_event
.destination
].addMsg(null, plugin_event
.nick
, plugin_event
.msg
);
460 onDebug: function (e
, data
) {
461 if (!kiwi
.front
.tabviewExists('kiwi_debug')) {
462 kiwi
.front
.tabviewAdd('kiwi_debug');
464 kiwi
.front
.tabviews
.kiwi_debug
.addMsg(null, ' ', data
.msg
);
467 onAction: function (e
, data
) {
469 // Is this message from a user?
470 if (data
.channel
=== kiwi
.gateway
.nick
) {
471 destination
= data
.nick
;
473 destination
= data
.channel
;
476 if (!kiwi
.front
.tabviewExists(destination
)) {
477 kiwi
.front
.tabviewAdd(destination
);
479 kiwi
.front
.tabviews
[destination
.toLowerCase()].addMsg(null, ' ', '* ' + data
.nick
+ ' ' + data
.msg
, 'action', 'color:#555;');
482 onTopic: function (e
, data
) {
483 if (kiwi
.front
.tabviewExists(data
.channel
)) {
484 kiwi
.front
.tabviews
[data
.channel
.toLowerCase()].changeTopic(data
.topic
);
488 onNotice: function (e
, data
) {
489 var nick
= (data
.nick
=== undefined) ? '' : data
.nick
,
490 enick
= '[' + nick
+ ']';
492 if (kiwi
.front
.tabviewExists(data
.target
)) {
493 kiwi
.front
.tabviews
[data
.target
.toLowerCase()].addMsg(null, enick
, data
.msg
, 'notice');
494 } else if (kiwi
.front
.tabviewExists(nick
)) {
495 kiwi
.front
.tabviews
[nick
.toLowerCase()].addMsg(null, enick
, data
.msg
, 'notice');
497 kiwi
.front
.tabviews
.server
.addMsg(null, enick
, data
.msg
, 'notice');
501 onCTCPRequest: function (e
, data
) {
502 var msg
= data
.msg
.split(" ", 2);
505 if (typeof msg
[1] === 'undefined') {
508 kiwi
.gateway
.notice(data
.nick
, String
.fromCharCode(1) + 'PING ' + msg
[1] + String
.fromCharCode(1));
511 kiwi
.gateway
.notice(data
.nick
, String
.fromCharCode(1) + 'TIME ' + (new Date()).toLocaleString() + String
.fromCharCode(1));
514 kiwi
.front
.tabviews
.server
.addMsg(null, 'CTCP [' + data
.nick
+ ']', data
.msg
, 'ctcp');
517 onCTCPResponse: function (e
, data
) {
520 onKiwi: function (e
, data
) {
524 onConnect: function (e
, data
) {
525 if (data
.connected
) {
526 if (kiwi
.gateway
.nick
!== data
.nick
) {
527 kiwi
.gateway
.nick
= data
.nick
;
528 kiwi
.front
.doLayout();
531 kiwi
.front
.tabviews
.server
.addMsg(null, ' ', '=== Connected OK :)', 'status');
532 if (typeof init_data
.channel
=== "string") {
533 kiwi
.front
.joinChannel(init_data
.channel
);
535 kiwi
.plugs
.run('connect', {success
: true});
537 kiwi
.front
.tabviews
.server
.addMsg(null, ' ', '=== Failed to connect :(', 'status');
538 kiwi
.plugs
.run('connect', {success
: false});
541 onConnectFail: function (e
, data
) {
542 var reason
= (typeof data
.reason
=== 'string') ? data
.reason
: '';
543 kiwi
.front
.tabviews
.server
.addMsg(null, '', 'There\'s a problem connecting! (' + reason
+ ')', 'error');
544 kiwi
.plugs
.run('connect', {success
: false});
546 onDisconnect: function (e
, data
) {
548 for (tab
in kiwi
.front
.tabviews
) {
549 kiwi
.front
.tabviews
[tab
].addMsg(null, '', 'Disconnected from server!', 'error');
551 kiwi
.plugs
.run('disconnect', {success
: false});
553 onOptions: function (e
, data
) {
554 if (typeof kiwi
.gateway
.network_name
=== "string" && kiwi
.gateway
.network_name
!== "") {
555 kiwi
.front
.tabviews
.server
.tab
.text(kiwi
.gateway
.network_name
);
558 onMOTD: function (e
, data
) {
559 kiwi
.front
.tabviews
.server
.addMsg(null, data
.server
, data
.msg
, 'motd');
561 onWhois: function (e
, data
) {
564 kiwi
.front
.cur_channel
.addMsg(null, data
.nick
, data
.msg
, 'whois');
565 } else if (data
.logon
) {
567 d
.setTime(data
.logon
* 1000);
568 d
= d
.toLocaleString();
569 kiwi
.front
.cur_channel
.addMsg(null, data
.nick
, 'idle for ' + data
.idle
+ ' second' + ((data
.idle
!== 1) ? 's' : '') + ', signed on ' + d
, 'whois');
571 kiwi
.front
.cur_channel
.addMsg(null, data
.nick
, 'idle for ' + data
.idle
+ ' seconds', 'whois');
574 onMode: function (e
, data
) {
575 var i
, new_nick_text
;
577 // TODO: Store the modes in the elements data, then work out the current
578 // mode symbol from the highest mode. Eg. -h may leave +o from previous modes; It
579 // doesn't simply clear it! ~Darren
580 if (typeof data
.channel
=== 'string' && typeof data
.effected_nick
=== 'string') {
581 kiwi
.front
.tabviews
[data
.channel
.toLowerCase()].addMsg(null, ' ', '[' + data
.mode
+ '] ' + data
.effected_nick
+ ' by ' + data
.nick
, 'mode', '');
582 kiwi
.front
.tabviews
[data
.channel
.toLowerCase()].userlist
.children().each(function () {
583 if (kiwi
.front
.nickStripPrefix($(this).text()) === data
.effected_nick
) {
585 if (data
.mode
.split('')[0] === '+') {
586 for (i
= 0; i
< kiwi
.gateway
.user_prefixes
.length
; i
++) {
587 if (kiwi
.gateway
.user_prefixes
[i
].mode
=== data
.mode
.split('')[1]) {
588 new_nick_text
= kiwi
.gateway
.user_prefixes
[i
].symbol
+ data
.effected_nick
;
592 } else if (data
.mode
.split('')[0] === '-') {
593 new_nick_text
= data
.effected_nick
;
596 if (new_nick_text
!== '') {
597 $(this).text(new_nick_text
);
605 onUserList: function (e
, data
) {
607 if (kiwi
.front
.tabviews
[data
.channel
.toLowerCase()] === undefined) {
610 ul
= kiwi
.front
.tabviews
[data
.channel
.toLowerCase()].userlist
;
612 if (!document
.userlist_updating
) {
613 document
.userlist_updating
= true;
617 $.each(data
.users
, function (i
, item
) {
618 nick
= i
; //i.match(/^.+!/g);
620 $('<li><a class="nick" onclick="kiwi.front.userClick(this);">' + mode
+ nick
+ '</a></li>').appendTo(ul
);
623 kiwi
.front
.tabviews
[data
.channel
.toLowerCase()].userlistSort();
625 onUserListEnd: function (e
, data
) {
626 document
.userlist_updating
= false;
629 onChannelListStart: function (e
, data
) {
631 console
.log('/list start');
632 console
.profile('list');
634 tab
= new Utilityview('Channel List');
635 tab
.div
.css('overflow-y', 'scroll');
636 table
= $('<table><thead style="font-weight: bold;"><tr><td>Channel Name</td><td>Members</td><td style="padding-left: 2em;">Topic</td></tr></thead><tbody style="vertical-align: top;"></tbody>');
637 tab
.div
.append(table
);
639 kiwi
.front
.cache
.list
= {chans
: [], tab
: tab
, table
: table
,
640 update: function (newChans
) {
641 var body
= this.table
.children('tbody:first').detach(),
646 for (chan
in newChans
) {
647 this.chans
.push(newChans
[chan
]);
648 html
+= newChans
[chan
].html
;
651 this.table
.append(body
);
654 finalise: function () {
655 var body
= this.table
.children('tbody:first').detach(),
659 list
= $.makeArray($(body
).children());
662 list
[chan
] = $(list
[chan
]).detach();
665 list
= _
.sortBy(list
, function (channel
) {
666 return parseInt(channel
.children('.num_users').first().text(), 10);
670 body
.append(list
[chan
]);
673 this.table
.append(body
);
677 onChannelList: function (e
, data
) {
682 for (chans
in data
) {
683 data
[chans
] = {data
: data
[chans
], html
: '<tr><td><a class="chan">' + data
[chans
].channel
+ '</a></td><td class="num_users" style="text-align: center;">' + data
[chans
].num_users
+ '</td><td style="padding-left: 2em;">' + kiwi
.front
.format(data
[chans
].topic
) + '</td></tr>'};
685 kiwi
.front
.cache
.list
.update(data
);
687 onChannelListEnd: function (e
, data
) {
688 kiwi
.front
.cache
.list
.finalise();
689 kiwi
.front
.cache
.list
.tab
.show();
690 console
.profileEnd();
691 console
.log('/list end.');
695 onJoin: function (e
, data
) {
696 if (!kiwi
.front
.tabviewExists(data
.channel
)) {
697 kiwi
.front
.tabviewAdd(data
.channel
.toLowerCase());
700 if (data
.nick
=== kiwi
.gateway
.nick
) {
701 return; // Not needed as it's already in nicklist
703 kiwi
.front
.tabviews
[data
.channel
.toLowerCase()].addMsg(null, ' ', '--> ' + data
.nick
+ ' has joined', 'action join', 'color:#009900;');
704 $('<li><a class="nick" onclick="kiwi.front.userClick(this);">' + data
.nick
+ '</a></li>').appendTo(kiwi
.front
.tabviews
[data
.channel
.toLowerCase()].userlist
);
705 kiwi
.front
.tabviews
[data
.channel
.toLowerCase()].userlistSort();
707 onPart: function (e
, data
) {
708 if (kiwi
.front
.tabviewExists(data
.channel
)) {
709 // If this is us, close the tabview
710 if (data
.nick
=== kiwi
.gateway
.nick
) {
711 kiwi
.front
.tabviews
[data
.channel
.toLowerCase()].close();
712 kiwi
.front
.tabviews
.server
.show();
716 kiwi
.front
.tabviews
[data
.channel
.toLowerCase()].addMsg(null, ' ', '<-- ' + data
.nick
+ ' has left (' + data
.message
+ ')', 'action part', 'color:#990000;');
717 kiwi
.front
.tabviews
[data
.channel
.toLowerCase()].userlist
.children().each(function () {
718 if ($(this).text() === data
.nick
) {
724 onKick: function (e
, data
) {
725 if (kiwi
.front
.tabviewExists(data
.channel
)) {
726 // If this is us, close the tabview
727 if (data
.kicked
=== kiwi
.gateway
.nick
) {
728 //kiwi.front.tabviews[data.channel.toLowerCase()].close();
729 kiwi
.front
.tabviews
[data
.channel
.toLowerCase()].addMsg(null, ' ', '=== You have been kicked from ' + data
.channel
+ '. ' + data
.message
, 'status kick');
730 kiwi
.front
.tabviews
[data
.channel
.toLowerCase()].safe_to_close
= true;
731 $('li', kiwi
.front
.tabviews
[data
.channel
.toLowerCase()].userlist
).remove();
735 kiwi
.front
.tabviews
[data
.channel
.toLowerCase()].addMsg(null, ' ', '<-- ' + data
.kicked
+ ' kicked by ' + data
.nick
+ '(' + data
.message
+ ')', 'action kick', 'color:#990000;');
736 kiwi
.front
.tabviews
[data
.channel
.toLowerCase()].userlist
.children().each(function () {
737 if ($(this).text() === data
.nick
) {
743 onNick: function (e
, data
) {
744 if (data
.nick
=== kiwi
.gateway
.nick
) {
745 kiwi
.gateway
.nick
= data
.newnick
;
746 kiwi
.front
.doLayout();
749 $.each(kiwi
.front
.tabviews
, function (i
, item
) {
750 $.each(kiwi
.front
.tabviews
, function (i
, item
) {
751 item
.changeNick(data
.newnick
, data
.nick
);
755 onQuit: function (e
, data
) {
756 $.each(kiwi
.front
.tabviews
, function (i
, item
) {
757 $.each(kiwi
.front
.tabviews
, function (i
, item
) {
758 item
.userlist
.children().each(function () {
759 if ($(this).text() === data
.nick
) {
761 item
.addMsg(null, ' ', '<-- ' + data
.nick
+ ' has quit (' + data
.message
+ ')', 'action quit', 'color:#990000;');
767 onChannelRedirect: function (e
, data
) {
768 kiwi
.front
.tabviews
[data
.from.toLowerCase()].close();
769 kiwi
.front
.tabviewAdd(data
.to
.toLowerCase());
770 kiwi
.front
.tabviews
[data
.to
.toLowerCase()].addMsg(null, ' ', '=== Redirected from ' + data
.from, 'action');
773 onIRCError: function (e
, data
) {
775 if (data
.channel
!== undefined && kiwi
.front
.tabviewExists(data
.channel
)) {
776 t_view
= data
.channel
;
781 switch (data
.error
) {
782 case 'banned_from_channel':
783 kiwi
.front
.tabviews
[t_view
].addMsg(null, ' ', '=== You are banned from ' + data
.channel
+ '. ' + data
.reason
, 'status');
784 if (t_view
!== 'server') {
785 kiwi
.front
.tabviews
[t_view
].safe_to_close
= true;
788 case 'bad_channel_key':
789 kiwi
.front
.tabviews
[t_view
].addMsg(null, ' ', '=== Bad channel key for ' + data
.channel
, 'status');
790 if (t_view
!== 'server') {
791 kiwi
.front
.tabviews
[t_view
].safe_to_close
= true;
794 case 'invite_only_channel':
795 kiwi
.front
.tabviews
[t_view
].addMsg(null, ' ', '=== ' + data
.channel
+ ' is invite only.', 'status');
796 if (t_view
!== 'server') {
797 kiwi
.front
.tabviews
[t_view
].safe_to_close
= true;
800 case 'channel_is_full':
801 kiwi
.front
.tabviews
[t_view
].addMsg(null, ' ', '=== ' + data
.channel
+ ' is full.', 'status');
802 if (t_view
!== 'server') {
803 kiwi
.front
.tabviews
[t_view
].safe_to_close
= true;
806 case 'chanop_privs_needed':
807 kiwi
.front
.tabviews
[data
.channel
].addMsg(null, ' ', '=== ' + data
.reason
, 'status');
810 kiwi
.front
.tabviews
.server
.addMsg(null, ' ', '=== ' + data
.nick
+ ': ' + data
.reason
, 'status');
812 case 'nickname_in_use':
813 kiwi
.front
.tabviews
.server
.addMsg(null, ' ', '=== The nickname ' + data
.nick
+ ' is already in use. Please select a new nickname', 'status');
814 kiwi
.front
.showChangeNick();
817 // We don't know what data contains, so don't do anything with it.
818 //kiwi.front.tabviews.server.addMsg(null, ' ', '=== ' + data, 'status');
822 registerKeys: function () {
823 $('#kiwi_msginput').bind('keydown', function (e
) {
824 var windows
, meta
, num
, msg
, data
, candidates
, word_pos
, word
, i
;
825 windows
= $('#windows');
826 //var meta = e.altKey;
830 case (e
.which
>= 48) && (e
.which
<= 57):
837 kiwi
.front
.windowsShow(num
);
841 case e
.which
=== 27: // escape
843 case e
.which
=== 13: // return
844 msg
= $('#kiwi_msginput').val();
847 kiwi
.front
.buffer
.push(msg
);
848 kiwi
.front
.buffer_pos
= kiwi
.front
.buffer
.length
;
851 $('#kiwi_msginput').val('');
854 case e
.which
=== 33: // page up
855 console
.log("page up");
856 windows
[0].scrollTop
= windows
[0].scrollTop
- windows
.height();
858 case e
.which
=== 34: // page down
859 windows
[0].scrollTop
= windows
[0].scrollTop
+ windows
.height();
861 case e
.which
=== 37: // left
863 kiwi
.front
.windowsPrevious();
867 case e
.which
=== 38: // up
868 if (kiwi
.front
.buffer_pos
> 0) {
869 kiwi
.front
.buffer_pos
--;
870 $('#kiwi_msginput').val(kiwi
.front
.buffer
[kiwi
.front
.buffer_pos
]);
873 case e
.which
=== 39: // right
875 kiwi
.front
.windowsNext();
879 case e
.which
=== 40: // down
880 if (kiwi
.front
.buffer_pos
< kiwi
.front
.buffer
.length
) {
881 kiwi
.front
.buffer_pos
++;
882 $('#kiwi_msginput').val(kiwi
.front
.buffer
[kiwi
.front
.buffer_pos
]);
886 case e
.which
=== 9: // tab
887 // Get possible autocompletions
889 kiwi
.front
.cur_channel
.userlist
.children().each(function () {
891 nick
= kiwi
.front
.nickStripPrefix($('a.nick', this).text());
895 // Do the autocomplete
896 if (this.value
.length
=== this.selectionStart
&& this.value
.length
=== this.selectionEnd
) {
899 word_pos
= this.value
.lastIndexOf(' ');
901 if (word_pos
=== -1) {
904 word
= this.value
.substr(word_pos
);
908 // filter data to find only strings that start with existing value
909 for (i
= 0; i
< data
.length
; i
++) {
910 if (data
[i
].indexOf(word
) === 0 && data
[i
].length
> word
.length
) {
911 candidates
.push(data
[i
]);
915 if (candidates
.length
> 0) {
916 // some candidates for autocompletion are found
917 this.value
= this.value
.substring(0, word_pos
) + ' ' + candidates
[0] + ': ';
918 this.selectionStart
= this.value
.length
;
926 $('#kiwi .control .msginput .nick').click(function () {
927 kiwi
.front
.showChangeNick();
934 $('#kiwi .plugins .load_plugin_file').click(function () {
935 if (typeof kiwi
.front
.boxes
.plugins
!== "undefined") {
939 kiwi
.front
.boxes
.plugins
= new Box("plugin_file");
940 $('#tmpl_plugins').tmpl({}).appendTo(kiwi
.front
.boxes
.plugins
.content
);
941 kiwi
.front
.boxes
.plugins
.box
.css('top', -(kiwi
.front
.boxes
.plugins
.height
+ 40));
943 // Populate the plugin list..
944 function enumPlugins() {
946 lst
= $('#plugin_list');
947 lst
.find('option').remove();
948 for (j
in kiwi
.plugs
.loaded
) {
949 txt
= kiwi
.plugs
.loaded
[j
].name
;
950 lst
.append('<option value="' + txt
+ '">' + txt
+ '</option>');
956 $('#kiwi .plugin_file').submit(function () {
957 $('<div></div>').load($('.txtpluginfile').val(), function (e
) {
962 $('#kiwi .cancelpluginfile').click(function () {
963 kiwi
.front
.boxes
.plugins
.destroy();
966 $('#kiwi #plugins_list_unload').click(function () {
968 selected_plugin
= $('#plugin_list').val();
969 kiwi
.plugs
.unloadPlugin(selected_plugin
);
973 $('#kiwi .txtpluginfile').focus();
977 $('#kiwi .plugins .reload_css').click(function () {
978 var links
= document
.getElementsByTagName("link"),
980 for (i
= 0; i
< links
.length
; i
++) {
981 if (links
[i
].rel
=== "stylesheet") {
982 if (links
[i
].href
.indexOf("?") === -1) {
983 links
[i
].href
+= "?";
985 links
[i
].href
+= "x";
991 $('#kiwi .about .about_close').click(function () {
992 $('#kiwi .about').css('display', 'none');
996 $('#kiwi .poweredby').click(function () {
997 $('#kiwi .about').css('display', 'block');
1003 showChangeNick: function () {
1004 $('#kiwi').append($('#tmpl_change_nick').tmpl({}));
1006 $('#kiwi .form_newnick').submit(function () {
1007 kiwi
.front
.run('/NICK ' + $('#kiwi .txtnewnick').val());
1008 $('#kiwi .newnick').remove();
1012 $('#kiwi .txtnewnick').keypress(function (ev
) {
1013 if (!this.first_press
) {
1014 this.first_press
= true;
1019 $('#kiwi .txtnewnick').keydown(function (ev
) {
1020 if (ev
.which
=== 27) { // ESC
1021 $('#kiwi_msginput').focus();
1022 $('#kiwi .newnick').remove();
1026 $('#kiwi .cancelnewnick').click(function () {
1027 $('#kiwi .newnick').remove();
1030 $('#kiwi .txtnewnick').focus();
1034 tabviewExists: function (name
) {
1035 return (typeof kiwi
.front
.tabviews
[name
.toLowerCase()] !== 'undefined');
1038 tabviewAdd: function (v_name
) {
1040 var re
, htmlsafe_name
, tmp_divname
, tmp_userlistname
, tmp_tabname
, userlist_enabled
= true;
1042 if (v_name
.charAt(0) === kiwi
.gateway
.channel_prefix
) {
1043 re
= new RegExp(kiwi
.gateway
.channel_prefix
, "g");
1044 htmlsafe_name
= v_name
.replace(re
, 'pre');
1045 htmlsafe_name
= "chan_" + htmlsafe_name
;
1047 htmlsafe_name
= 'query_' + v_name
;
1048 userlist_enabled
= false;
1051 tmp_divname
= 'kiwi_window_' + htmlsafe_name
;
1052 tmp_userlistname
= 'kiwi_userlist_' + htmlsafe_name
;
1053 tmp_tabname
= 'kiwi_tab_' + htmlsafe_name
;
1055 if (!kiwi
.front
.tabviewExists(v_name
)) {
1056 $('#kiwi .windows .scroller').append('<div id="' + tmp_divname
+ '" class="messages"></div>');
1057 $('#kiwi .userlist').append('<ul id="' + tmp_userlistname
+ '"></ul>');
1058 $('#kiwi .windowlist ul').append('<li id="' + tmp_tabname
+ '" onclick="kiwi.front.tabviews[\'' + v_name
.toLowerCase() + '\'].show();">' + v_name
+ '</li>');
1060 //$('#kiwi .windowlist ul .window_'+v_name).click(function(){ kiwi.front.windowShow(v_name); });
1061 //kiwi.front.windowShow(v_name);
1063 kiwi
.front
.tabviews
[v_name
.toLowerCase()] = new Tabview();
1064 kiwi
.front
.tabviews
[v_name
.toLowerCase()].name
= v_name
;
1065 kiwi
.front
.tabviews
[v_name
.toLowerCase()].div
= $('#' + tmp_divname
);
1066 kiwi
.front
.tabviews
[v_name
.toLowerCase()].userlist
= $('#' + tmp_userlistname
);
1067 kiwi
.front
.tabviews
[v_name
.toLowerCase()].tab
= $('#' + tmp_tabname
);
1068 if (!userlist_enabled
) {
1069 kiwi
.front
.tabviews
[v_name
.toLowerCase()].userlist_width
= 0;
1071 kiwi
.front
.tabviews
[v_name
.toLowerCase()].show();
1073 if (typeof registerTouches
=== "function") {
1074 //alert("Registering touch interface");
1075 //registerTouches($('#'+tmp_divname));
1076 registerTouches(document
.getElementById(tmp_divname
));
1079 kiwi.front.tabviews[v_name.toLowerCase()].userlist.click(function(){
1080 alert($(this).attr('id'));
1084 kiwi
.front
.doLayoutSize();
1088 userClick: function (item
) {
1089 var li
= $(item
).parent();
1091 // Remove any existing userboxes
1092 $('#kiwi .userbox').remove();
1094 if ($(li
).data('userbox') === item
) {
1095 $(li
).removeData('userbox');
1097 $('#tmpl_user_box').tmpl({nick
: kiwi
.front
.nickStripPrefix($(item
).text())}).appendTo(li
);
1099 $('#kiwi .userbox .userbox_query').click(function (ev
) {
1100 var nick
= $('#kiwi .userbox_nick').val();
1101 kiwi
.front
.run('/query ' + nick
);
1104 $('#kiwi .userbox .userbox_whois').click(function (ev
) {
1105 var nick
= $('#kiwi .userbox_nick').val();
1106 kiwi
.front
.run('/whois ' + nick
);
1108 $(li
).data('userbox', item
);
1114 kiwi
.gateway
.sync();
1117 onSync: function (e
, data
) {
1119 if (data
.nick
!== undefined) {
1120 kiwi
.gateway
.nick
= data
.nick
;
1124 if (data
.tabviews
!== undefined) {
1125 $.each(data
.tabviews
, function (i
, tab
) {
1126 if (!kiwi
.front
.tabviewExists(tab
.name
)) {
1127 kiwi
.front
.tabviewAdd(kiwi
.gateway
.channel_prefix
+ tab
.name
);
1129 if (tab
.userlist
!== undefined) {
1130 kiwi
.front
.onUserList({'channel': kiwi
.gateway
.channel_prefix
+ tab
.name
, 'users': tab
.userlist
});
1136 kiwi
.front
.doLayout();
1140 setTopicText: function (new_topic
) {
1141 kiwi
.front
.original_topic
= new_topic
;
1142 $('#kiwi .cur_topic .topic').text(kiwi
.front
.format(new_topic
));
1143 kiwi
.front
.doLayoutSize();
1146 nickStripPrefix: function (nick
) {
1147 var tmp
= nick
, i
, prefix
;
1149 prefix
= tmp
.charAt(0);
1150 for (i
in kiwi
.gateway
.user_prefixes
) {
1151 if (kiwi
.gateway
.user_prefixes
[i
].symbol
=== prefix
) {
1152 return tmp
.substring(1);
1159 nickGetPrefix: function (nick
) {
1160 var tmp
= nick
, i
, prefix
;
1162 prefix
= tmp
.charAt(0);
1163 for (i
in kiwi
.gateway
.user_prefixes
) {
1164 if (kiwi
.gateway
.user_prefixes
[i
].symbol
=== prefix
) {
1172 isChannel: function (name
) {
1173 var prefix
, is_chan
;
1174 prefix
= name
.charAt(0);
1175 if (kiwi
.gateway
.channel_prefix
.indexOf(prefix
) > -1) {
1184 tabviewsNext: function () {
1185 var wl
= $('#kiwi .windowlist ul'),
1186 next_left
= parseInt(wl
.css('text-indent').replace('px', ''), 10) + 170;
1187 wl
.css('text-indent', next_left
);
1190 tabviewsPrevious: function () {
1191 var wl
= $('#kiwi .windowlist ul'),
1192 next_left
= parseInt(wl
.css('text-indent').replace('px', ''), 10) - 170;
1193 wl
.css('text-indent', next_left
);
1196 windowsNext: function () {
1199 for (tab
in kiwi
.front
.tabviews
) {
1201 if (kiwi
.front
.tabviews
[tab
] === kiwi
.front
.cur_channel
) {
1206 kiwi
.front
.tabviews
[tab
].show();
1212 windowsPrevious: function () {
1213 var tab
, prev_tab
, next
;
1215 for (tab
in kiwi
.front
.tabviews
) {
1216 if (kiwi
.front
.tabviews
[tab
] === kiwi
.front
.cur_channel
) {
1222 prev_tab
= kiwi
.front
.tabviews
[tab
];
1226 windowsShow: function (num
) {
1227 num
= parseInt(num
, 10);
1228 console
.log('Showing window ' + num
.toString());
1230 for (tab
in kiwi
.front
.tabviews
) {
1232 kiwi
.front
.tabviews
[tab
].show();
1241 barsShow: function () {
1242 $('#kiwi .toolbars').slideDown();
1243 $('#kiwi .control').slideDown();
1246 barsHide: function () {
1247 $('#kiwi .toolbars').slideUp();
1248 $('#kiwi .control').slideUp();
1251 format: function (msg
) {
1254 if ((!msg
) || (typeof msg
!== 'string')) {
1259 if (msg
.indexOf(String
.fromCharCode(2)) !== -1) {
1261 while (msg
.indexOf(String
.fromCharCode(2)) !== -1) {
1262 msg
= msg
.replace(String
.fromCharCode(2), next
);
1263 next
= (next
=== '<b>') ? '</b>' : '<b>';
1265 if (next
=== '</b>') {
1271 if (msg
.indexOf(String
.fromCharCode(31)) !== -1) {
1273 while (msg
.indexOf(String
.fromCharCode(31)) !== -1) {
1274 msg
= msg
.replace(String
.fromCharCode(31), next
);
1275 next
= (next
=== '<u>') ? '</u>' : '<u>';
1277 if (next
=== '</u>') {
1283 re
= /\x03([0-9][0-5]?)(,([0-9][0-5]?))?(.*?)\x03/g;
1285 msg
= msg
.replace(re
, function (str
, p1
, p2
, p3
, p4
) {
1287 col = function (num
) {
1288 switch (parseInt(num
, 10)) {
1327 return '<span style="' + ((fg
!== null) ? 'color: ' + fg
+ '; ' : '') + ((bg
!== null) ? 'background-color: ' + bg
+ ';' : '') + '">' + p4
+ '</span>';
1353 var Utilityview = function (name
) {
1354 var rand_name
= randomString(15),
1355 tmp_divname
= 'kiwi_window_' + rand_name
,
1356 tmp_userlistname
= 'kiwi_userlist_' + rand_name
,
1357 tmp_tabname
= 'kiwi_tab_' + rand_name
;
1359 this.name
= rand_name
;
1363 $('#kiwi .windows .scroller').append('<div id="' + tmp_divname
+ '" class="messages"></div>');
1365 this.tab
= $('<li id="' + tmp_tabname
+ '">' + this.title
+ '</li>');
1366 this.tab
.click(function () {
1367 kiwi
.front
.utilityviews
[rand_name
.toLowerCase()].show();
1369 $('#kiwi .utilityviewlist ul').append(this.tab
);
1371 this.div
= $('#' + tmp_divname
);
1372 this.div
.css('overflow', 'hidden');
1374 kiwi
.front
.utilityviews
[rand_name
.toLowerCase()] = this;
1377 Utilityview
.prototype.name
= null;
1378 Utilityview
.prototype.title
= null;
1379 Utilityview
.prototype.div
= null;
1380 Utilityview
.prototype.tab
= null;
1381 Utilityview
.prototype.topic
= ' ';
1382 Utilityview
.prototype.show = function () {
1383 $('#kiwi .messages').removeClass("active");
1384 $('#kiwi .userlist ul').removeClass("active");
1385 $('#kiwi .toolbars ul li').removeClass("active");
1387 $('#windows').css('overflow-y', 'hidden');
1388 $('#windows').css('right', 0);
1389 // Activate this tab!
1390 this.div
.addClass('active');
1391 this.tab
.addClass('active');
1393 this.addPartImage();
1395 kiwi
.front
.setTopicText(this.topic
);
1396 kiwi
.front
.cur_channel
= this;
1398 // If we're using fancy scrolling, refresh it
1400 touch_scroll
.refresh();
1404 Utilityview
.prototype.close = function () {
1408 if (kiwi
.front
.cur_channel
=== this) {
1409 kiwi
.front
.tabviews
.server
.show();
1411 delete kiwi
.front
.utilityviews
[this.name
.toLowerCase()];
1414 Utilityview
.prototype.addPartImage = function () {
1415 this.clearPartImage();
1417 // We can't close this tab, so don't have the close image
1418 if (this.name
=== 'server') {
1422 var del_html
= '<img src="/img/redcross.png" class="tab_part" />';
1423 this.tab
.append(del_html
);
1425 $('.tab_part', this.tab
).click(function () {
1426 if (kiwi
.front
.cur_channel
.name
!== 'server') {
1427 kiwi
.front
.cur_channel
.close();
1432 Utilityview
.prototype.clearPartImage = function () {
1433 $('#kiwi .toolbars .tab_part').remove();
1447 var Tabview = function () {};
1448 Tabview
.prototype.name
= null;
1449 Tabview
.prototype.div
= null;
1450 Tabview
.prototype.userlist
= null;
1451 Tabview
.prototype.userlist_width
= 100; // 0 for disabled
1452 Tabview
.prototype.tab
= null;
1453 Tabview
.prototype.topic
= "";
1454 Tabview
.prototype.safe_to_close
= false; // If we have been kicked/banned/etc from this channel, don't wait for a part message
1456 Tabview
.prototype.show = function () {
1459 $('#kiwi .messages').removeClass("active");
1460 $('#kiwi .userlist ul').removeClass("active");
1461 $('#kiwi .toolbars ul li').removeClass("active");
1464 u
= $('#kiwi .userlist');
1466 w
.css('overflow-y', 'scroll');
1468 // Set the window size accordingly
1469 this.setUserlistWidth();
1471 // Activate this tab!
1472 this.div
.addClass('active');
1473 if (this.userlist_width
> 0) {
1474 this.userlist
.addClass('active');
1475 // Enable the userlist resizer
1476 $('#nicklist_resize').css('display', 'block');
1478 // Disable the userlist resizer
1479 $('#nicklist_resize').css('display', 'none');
1481 this.tab
.addClass('active');
1483 // Add the part image to the tab
1484 this.addPartImage();
1486 this.clearHighlight();
1487 kiwi
.front
.setTopicText(this.topic
);
1488 kiwi
.front
.cur_channel
= this;
1490 // If we're using fancy scrolling, refresh it
1492 touch_scroll
.refresh();
1495 this.scrollBottom();
1497 $('#kiwi_msginput').focus();
1501 Tabview
.prototype.close = function () {
1503 this.userlist
.remove();
1506 if (kiwi
.front
.cur_channel
=== this) {
1507 kiwi
.front
.tabviews
.server
.show();
1509 delete kiwi
.front
.tabviews
[this.name
.toLowerCase()];
1512 Tabview
.prototype.setUserlistWidth = function (new_width
) {
1514 if (typeof new_width
=== 'number') {
1515 this.userlist_width
= new_width
;
1519 u
= $('#kiwi .userlist');
1521 // Set the window size accordingly
1522 if (this.userlist_width
> 0) {
1523 u
.width(this.userlist_width
);
1524 w
.css('right', u
.outerWidth(true));
1530 Tabview
.prototype.addPartImage = function () {
1531 this.clearPartImage();
1533 // We can't close this tab, so don't have the close image
1534 if (this.name
=== 'server') {
1538 var del_html
= '<img src="/img/redcross.png" class="tab_part" />';
1539 this.tab
.append(del_html
);
1541 $('.tab_part', this.tab
).click(function () {
1542 if (kiwi
.front
.isChannel($(this).parent().text())) {
1543 kiwi
.front
.run("/part");
1545 // Make sure we don't close the server tab
1546 if (kiwi
.front
.cur_channel
.name
!== 'server') {
1547 kiwi
.front
.cur_channel
.close();
1553 Tabview
.prototype.clearPartImage = function () {
1554 $('#kiwi .toolbars .tab_part').remove();
1557 Tabview
.prototype.addMsg = function (time
, nick
, msg
, type
, style
) {
1558 var self
, tmp
, plugin_ret
, i
, d
, re
, line_msg
, next
;
1562 tmp
= {msg
: msg
, time
: time
, nick
: nick
, tabview
: this.name
};
1563 tmp
= kiwi
.plugs
.run('addmsg', tmp
);
1573 if (time
=== null) {
1575 time
= d
.getHours().toString().lpad(2, "0") + ":" + d
.getMinutes().toString().lpad(2, "0") + ":" + d
.getSeconds().toString().lpad(2, "0");
1578 // The CSS class (action, topic, notice, etc)
1579 if (typeof type
!== "string") {
1583 // Make sure we don't have NaN or something
1584 if (typeof msg
!== "string") {
1588 // Make the channels clickable
1589 re
= new RegExp('\\B(' + kiwi
.gateway
.channel_prefix
+ '[^ ,.\\007]+)', 'g');
1590 msg
= msg
.replace(re
, function (match
) {
1591 return '<a class="chan">' + match
+ '</a>';
1594 msg
= kiwi
.front
.format(msg
);
1596 // Build up and add the line
1597 line_msg
= $('<div class="msg ' + type
+ '"><div class="time">' + time
+ '</div><div class="nick">' + nick
+ '</div><div class="text" style="' + style
+ '">' + msg
+ ' </div></div>');
1598 this.div
.append(line_msg
);
1601 this.scrollBottom();
1603 touch_scroll
.refresh();
1604 //console.log(this.div.attr("scrollHeight") +" - "+ $('#windows').height());
1605 this.scrollBottom();
1606 //if(this.div.attr("scrollHeight") > $('#windows').height()){
1607 // touch_scroll.scrollTo(0, this.div.height());
1612 Tabview
.prototype.scrollBottom = function () {
1613 var w
= $('#windows');
1614 w
[0].scrollTop
= w
[0].scrollHeight
;
1617 Tabview
.prototype.changeNick = function (newNick
, oldNick
) {
1618 this.userlist
.children().each(function () {
1619 var item
= $('a.nick', this);
1620 if (kiwi
.front
.nickStripPrefix(item
.text()) === oldNick
) {
1621 item
.text(kiwi
.front
.nickGetPrefix(item
.text()) + newNick
);
1622 document
.temp_chan
= 1;
1626 if (typeof document
.temp_chan
!== "undefined") {
1627 this.addMsg(null, ' ', '=== ' + oldNick
+ ' is now known as ' + newNick
, 'action changenick');
1628 delete document
.temp_chan
;
1629 this.userlistSort();
1633 Tabview
.prototype.userlistSort = function () {
1634 var ul
= this.userlist
,
1635 listitems
= ul
.children('li').get(),
1637 listitems
.sort(function (a
, b
) {
1638 var compA
= $(a
).text().toUpperCase(),
1639 compB
= $(b
).text().toUpperCase(),
1642 // Sort by prefixes first
1643 for (i
in kiwi
.gateway
.user_prefixes
) {
1644 prefix
= kiwi
.gateway
.user_prefixes
[i
].symbol
;
1646 if (compA
.charAt(0) === prefix
&& compB
.charAt(0) === prefix
) {
1647 // Both have the same prefix, string compare time
1651 if (compA
.charAt(0) === prefix
&& compB
.charAt(0) !== prefix
) {
1655 if (compA
.charAt(0) !== prefix
&& compB
.charAt(0) === prefix
) {
1660 // No prefixes, compare by string
1661 return (compA
< compB
) ? -1 : (compA
> compB
) ? 1 : 0;
1663 $.each(listitems
, function (idx
, itm
) { ul
.append(itm
); });
1666 Tabview
.prototype.highlight = function () {
1667 this.tab
.addClass('highlight');
1669 Tabview
.prototype.activity = function () {
1670 this.tab
.addClass('activity');
1672 Tabview
.prototype.clearHighlight = function () {
1673 this.tab
.removeClass('highlight');
1674 this.tab
.removeClass('activity');
1676 Tabview
.prototype.changeTopic = function (new_topic
) {
1677 this.topic
= new_topic
;
1678 this.addMsg(null, ' ', '=== Topic for ' + this.name
+ ' is: ' + new_topic
, 'topic');
1679 if (kiwi
.front
.cur_channel
.name
=== this.name
) {
1680 kiwi
.front
.setTopicText(new_topic
);
1688 var Box = function (classname
) {
1689 this.id
= randomString(10);
1690 var tmp
= $('<div id="' + this.id
+ '" class="box ' + classname
+ '"><div class="boxarea"></div></div>');
1691 $('#kiwi').append(tmp
);
1692 this.box
= $('#' + this.id
);
1693 this.content
= $('#' + this.id
+ ' .boxarea');
1695 this.box
.draggable({ stack
: ".box" });
1696 this.content
.click(function () {});
1697 //this.box.click(function(){ $(this)..css });
1699 Box
.prototype.create = function (name
, classname
) {
1702 Box
.prototype.id
= null;
1703 Box
.prototype.box
= null;
1704 Box
.prototype.content
= null;
1705 Box
.prototype.destroy = function () {
1708 for (name
in kiwi
.front
.boxes
) {
1709 if (kiwi
.front
.boxes
[name
].id
=== this.id
) {
1710 delete kiwi
.front
.boxes
[name
];
1714 Box
.prototype.height = function () {
1715 return this.box
.height();