Window clsoe confirmation if connected
[KiwiIRC.git] / client / js / front.js
CommitLineData
8343584e
D
1/*jslint white:true, regexp: true, nomen: true, devel: true, undef: true, browser: true, continue: true, sloppy: true, forin: true, newcap: true, plusplus: true, maxerr: 50, indent: 4 */
2/*global kiwi, _, io, $, iScroll, agent, touchscreen, init_data, plugs, plugins, registerTouches, randomString */
5a29866a
JA
3/**
4* @namespace
5*/
673a7c8f 6kiwi.front = {
5a29866a
JA
7 /**
8 * The current channel
9 * @type Object
10 */
11 cur_channel: null,
12 /**
13 * A list of windows
14 * @type Object
15 */
a3364605 16 windows: {},
5a29866a
JA
17 /**
18 * A list of Tabviews
19 * @type Object
20 */
a3364605 21 tabviews: {},
5a29866a
JA
22 /**
23 * A list of Utilityviews
24 * @type Object
25 */
604c5174 26 utilityviews: {},
5a29866a
JA
27 /**
28 * A list of Boxes
29 * @type Object
30 */
a3364605 31 boxes: {},
8343584e 32
5a29866a
JA
33 /**
34 * The command history
35 * @type Array
36 */
37 buffer: [],
38 /**
39 * The current command history position
40 * @type Number
41 */
42 buffer_pos: 0,
43
44 /**
45 * Container for misc data (eg. userlist generation)
46 * @type Object
47 */
bfdeb872 48 cache: {original_topic: '', userlist: {}},
8343584e 49
5a29866a
JA
50 /**
51 * Initialisation function
52 */
a3364605 53 init: function () {
1fce4b40
JA
54 /*global Box, touch_scroll:true, Tabview */
55 var about_info, supportsOrientationChange, orientationEvent, scroll_opts, server_tabview;
673a7c8f
D
56 kiwi.gateway.nick = 'kiwi_' + Math.ceil(100 * Math.random()) + Math.ceil(100 * Math.random());
57 kiwi.gateway.session_id = null;
8343584e 58
b41a381f
D
59 // Bind to the gateway events
60 kiwi.front.events.bindAll();
8343584e 61
a3364605 62 // Build the about box
673a7c8f 63 kiwi.front.boxes.about = new Box("about");
a3364605
JA
64 about_info = 'UI adapted for ' + agent;
65 if (touchscreen) {
66 about_info += ' touchscreen ';
67 }
68 about_info += 'usage';
69 $('#tmpl_about_box').tmpl({
47468e80 70 about: about_info
673a7c8f 71 }).appendTo(kiwi.front.boxes.about.content);
a3364605 72
673a7c8f 73 //$(window).bind("beforeunload", function(){ kiwi.gateway.quit(); });
8343584e 74
a3364605
JA
75 if (touchscreen) {
76 $('#kiwi').addClass('touchscreen');
77
78 // Single touch scrolling through scrollback for touchscreens
79 scroll_opts = {};
80 touch_scroll = new iScroll('windows', scroll_opts);
81 }
82
b41a381f 83 kiwi.front.ui.registerKeys();
8343584e 84
b41a381f
D
85 $('#kiwi .toolbars').resize(kiwi.front.ui.doLayoutSize);
86 $(window).resize(kiwi.front.ui.doLayoutSize);
b10afa2d
D
87
88 // Add the resizer for the userlist
b6ee5d82 89 $('<div id="nicklist_resize"></div>').appendTo('#kiwi');
80c584e7
JA
90 $('#nicklist_resize').draggable({axis: "x", drag: function () {
91 var t = $(this),
7779d29a 92 ul = $('#kiwi .userlist'),
fde6ea95 93 new_width = $(document).width() - parseInt(t.css('left'), 10);
8343584e 94
7779d29a
D
95 new_width = new_width - parseInt(ul.css('margin-left'), 10);
96 new_width = new_width - parseInt(ul.css('margin-right'), 10);
b10afa2d
D
97
98 // Make sure we don't remove the userlist alltogether
b10afa2d
D
99 if (new_width < 20) {
100 $(this).data('draggable').offset.click.left = 10;
101 console.log('whoaa');
102 }
103
bb6a9775
JA
104 var members = kiwi.currentPanel.get("members");
105 if (members) {
106 $(members.view.el).width(new_width);
107 }
7779d29a 108 $('#windows').css('right', ul.outerWidth(true));
b10afa2d
D
109 }});
110
a3364605
JA
111
112 $('#kiwi .formconnectwindow').submit(function () {
113 var netsel = $('#kiwi .formconnectwindow .network'),
46f98bec
JA
114 netport = $('#kiwi .formconnectwindow .port'),
115 netssl = $('#kiwi .formconnectwindow .ssl'),
e8a707e7 116 netpass = $('#kiwi .formconnectwindow .password'),
a3364605 117 nick = $('#kiwi .formconnectwindow .nick'),
6849bc6c
JA
118 tmp,
119 forwardKeys;
8343584e 120
a3364605
JA
121 if (nick.val() === '') {
122 nick.val('Nick please!');
123 nick.focus();
124 return false;
125 }
8343584e 126
a3364605 127 tmp = nick.val().split(' ');
673a7c8f 128 kiwi.gateway.nick = tmp[0];
c89b9fdf
D
129
130 init_data.channel = $('#channel').val();
131
b41a381f 132 kiwi.front.ui.doLayout();
a3364605 133 try {
bb6a9775
JA
134 kiwi.gateway.connect(netsel.val(), netport.val(), netssl.is(':checked'), netpass.val(), function () {
135 setTimeout(function () {
136 kiwi.channels.server.set({"name": netsel.val()});
137 kiwi.channels.view.render();
138 }, 0);
139 });
4c408915
D
140 } catch (e) {
141 console.log(e);
142 }
8343584e 143
b41a381f 144 $('#kiwi .connectwindow').slideUp('', kiwi.front.ui.barsShow);
6849bc6c 145
5a29866a
JA
146 /**
147 * Listen for keyboard activity on any window, and forward it to the
148 * input box so users can type even if the input box is not in focus
149 * @inner
150 * @param {eventObject} event The event to forward
151 */
6849bc6c
JA
152 forwardKeys = function (event) {
153 $('#kiwi_msginput').focus();
154 $('#kiwi_msginput').trigger(event);
155 };
156 $('#kiwi_msginput').attr('tabindex', 0);
157 $('#kiwi_msginput').focus();
158 $('#windows').attr('tabindex',100);
159 $('#windows').keydown(forwardKeys).keypress(forwardKeys).keyup(forwardKeys);
a3364605
JA
160
161 return false;
162 });
163
164 supportsOrientationChange = (typeof window.onorientationchange !== undefined);
165 orientationEvent = supportsOrientationChange ? "orientationchange" : "resize";
d30da6a0 166 if (window.addEventListener) {
b41a381f 167 window.addEventListener(orientationEvent, kiwi.front.ui.doLayoutSize, false);
d30da6a0
D
168 } else {
169 // < IE9
b41a381f 170 window.attachEvent(orientationEvent, kiwi.front.ui.doLayoutSize, false);
d30da6a0 171 }
b41a381f 172 //$('#kiwi').bind("resize", kiwi.front.ui.doLayoutSize, false);
a3364605 173
b41a381f
D
174 kiwi.front.ui.doLayout();
175 kiwi.front.ui.barsHide();
8343584e 176
bb6a9775 177 kiwi.channels = new kiwi.model.PanelList();
f7a9a13c
JA
178
179
54a2a4e1
JA
180 //server_tabview = new Tabview('server');
181 //server_tabview.userlist.setWidth(0); // Disable the userlist
182 //server_tabview.setIcon('/img/app_menu.png');
183 //$('.icon', server_tabview.tab).tipTip({
184 // delay: 0,
185 // keepAlive: true,
186 // content: $('#tmpl_network_menu').tmpl({}).html(),
187 // activation: 'click'
188 //});
8343584e 189
a3364605 190 // Any pre-defined nick?
c89b9fdf 191 if (typeof window.init_data.nick === "string") {
bad1ea63
JA
192 $('#kiwi .formconnectwindow .nick').val(init_data.nick);
193 }
c89b9fdf
D
194
195 // Any pre-defined channels?
196 if (typeof window.init_data.channel === 'string') {
197 $('#channel').val(init_data.channel);
198 }
8343584e 199
8ee99eba
JA
200 // Fix for Opera inserting a spurious <br/>
201 $('#kiwi .cur_topic br').remove();
8343584e 202
a3364605 203 $('#kiwi .cur_topic').keydown(function (e) {
aa191535
D
204 if (e.which === 13) {
205 // enter
206 e.preventDefault();
207 $(this).change();
208 $('#kiwi_msginput').focus();
209 } else if (e.which === 27) {
210 // escape
211 e.preventDefault();
bfdeb872 212 $(this).text(kiwi.front.cache.original_topic);
aa191535
D
213 $('#kiwi_msginput').focus();
214 }
a3364605 215 });
aa191535 216 /*$('.cur_topic').live('keypress', function(e) {
110ce6d4 217 if (e.keyCode === 13) {
1666d8d9 218 // enter
110ce6d4
JA
219 e.preventDefault();
220 $(this).change();
221 $('#kiwi_msginput').focus();
1666d8d9
JA
222 } else if (e.keyCode === 27) {
223 // escape
224 e.preventDefault();
bfdeb872 225 $(this).text(kiwi.front.cache.original_topic);
110ce6d4 226 }
aa191535 227 });*/
a3364605 228 $('.cur_topic').live('change', function () {
110ce6d4
JA
229 var chan, text;
230 text = $(this).text();
bfdeb872 231 if (text !== kiwi.front.cache.original_topic) {
bb6a9775
JA
232 if (kiwi.currentPanel.isChannel) {
233 kiwi.gateway.topic(kiwi.currentPannel.get("name"), text);
234 }
110ce6d4
JA
235 }
236 });
ff19dc74
D
237
238
c6ef62a3 239 $('#windows a.chan').live('click', function () {
673a7c8f 240 kiwi.front.joinChannel($(this).text());
ff19dc74
D
241 return false;
242 });
8343584e 243
fde6ea95 244 kiwi.data.set('chanList', []);
abb46d2d 245
604eaa7d 246 // Load any client plugins
2fc64ec2
JA
247 (function () {
248 var i;
249 for (i in plugins) {
673a7c8f 250 kiwi.plugs.loadPlugin(plugins[i]);
2fc64ec2
JA
251 }
252 }());
a3364605 253 },
8343584e 254
a3364605 255
8343584e 256
5a29866a
JA
257 /**
258 * Joins a channel
259 * @param {String} chan_name The name of the channel to join
260 */
a3364605
JA
261 joinChannel: function (chan_name) {
262 var chans = chan_name.split(','),
c6ef62a3 263 i,
1fce4b40 264 chan,
bb6a9775 265 panel;
a3364605
JA
266 for (i in chans) {
267 chan = chans[i];
bb6a9775
JA
268 panel = kiwi.channels.getByName(chan);
269 if (!panel) {
673a7c8f 270 kiwi.gateway.join(chan);
bb6a9775 271 }
a3364605
JA
272 }
273 },
8343584e 274
5a29866a
JA
275 /**
276 * Parses and executes text and commands entered into the input msg box
277 * @param {String} msg The message string to parse
278 */
a3364605 279 run: function (msg) {
bb6a9775 280 var parts, dest, t, pos, textRange, plugin_event, msg_sliced, tab, nick, panel;
8343584e 281
875d0c71
D
282 // Run through any plugins
283 plugin_event = {command: msg};
673a7c8f 284 plugin_event = kiwi.plugs.run('command_run', plugin_event);
c6ef62a3
JA
285 if (!plugin_event || typeof plugin_event.command === 'undefined') {
286 return;
287 }
875d0c71
D
288
289 // Update msg if it's been changed by any plugins
290 msg = plugin_event.command.toString();
291
8343584e 292
a3364605 293 if (msg.substring(0, 1) === '/') {
cd81360a 294 console.log("running " + msg);
a3364605
JA
295 parts = msg.split(' ');
296 switch (parts[0].toLowerCase()) {
297 case '/j':
298 case '/join':
673a7c8f 299 kiwi.front.joinChannel(parts[1]);
a3364605 300 break;
8343584e 301
a3364605
JA
302 case '/connect':
303 case '/server':
4c408915 304 if (typeof parts[1] === 'undefined') {
e8a707e7 305 alert('Usage: /connect servername [port] [ssl] [password]');
a3364605
JA
306 break;
307 }
8343584e 308
4c408915 309 if (typeof parts[2] === 'undefined') {
bad1ea63
JA
310 parts[2] = 6667;
311 }
8343584e 312
4c408915 313 if ((typeof parts[3] === 'undefined') || !parts[3] || (parts[3] === 'false') || (parts[3] === 'no')) {
46f98bec
JA
314 parts[3] = false;
315 } else {
316 parts[3] = true;
317 }
8343584e 318
bb6a9775 319 kiwi.channels.server.addMsg(null, ' ', '=== Connecting to ' + parts[1] + ' on port ' + parts[2] + (parts[3] ? ' using SSL' : '') + '...', 'status');
54a2a4e1 320 console.log('Connecting to ' + parts[1] + ' on port ' + parts[2] + (parts[3] ? ' using SSL' : '') + '...');
e8a707e7 321 kiwi.gateway.connect(parts[1], parts[2], parts[3], parts[4]);
a3364605 322 break;
8343584e 323
a3364605
JA
324 case '/nick':
325 console.log("/nick");
326 if (parts[1] === undefined) {
327 console.log("calling show nick");
b41a381f 328 kiwi.front.ui.showChangeNick();
a3364605 329 } else {
312d2d7c 330 console.log("sending nick");
5d57d62d 331 kiwi.gateway.changeNick(parts[1]);
a3364605
JA
332 }
333 break;
334
335 case '/part':
336 if (typeof parts[1] === "undefined") {
bb6a9775
JA
337 if (kiwi.currentPanel.isChannel) {
338 kiwi.gateway.part(kiwi.currentPanel.get("name"));
339 }
a3364605 340 } else {
312d2d7c 341 kiwi.gateway.part(msg.substring(6));
a3364605
JA
342 }
343 break;
8343584e 344
a3364605
JA
345 case '/names':
346 if (typeof parts[1] !== "undefined") {
673a7c8f 347 kiwi.gateway.raw(msg.substring(1));
bb6a9775
JA
348 } else {
349 if (kiwi.currentPanel.isChannel) {
350 kiwi.gateway.raw("NAMES " + kiwi.currentPanel.get("name"));
351 }
a3364605
JA
352 }
353 break;
8343584e 354
a3364605 355 case '/debug':
673a7c8f 356 kiwi.gateway.debug();
a3364605 357 break;
8343584e 358
a3364605
JA
359 case '/q':
360 case '/query':
361 if (typeof parts[1] !== "undefined") {
54a2a4e1 362 //tab = new Tabview(parts[1]);
a3364605
JA
363 }
364 break;
323e90f6 365
8343584e 366
323e90f6
D
367 case '/m':
368 case '/msg':
369 if (typeof parts[1] !== "undefined") {
c6ef62a3 370 msg_sliced = msg.split(' ').slice(2).join(' ');
312d2d7c 371 kiwi.gateway.privmsg(parts[1], msg_sliced);
a5ffcf00 372
bb6a9775
JA
373 // TODO: Queries
374 panel = kiwi.channels.getByName(parts[1]);
375 if (panel) {
376 panel.addMsg(null, kiwi.gateway.nick, msg_sliced);
377 }
323e90f6
D
378 }
379 break;
8343584e 380
cdd803f6
D
381 case '/k':
382 case '/kick':
80c584e7 383 if (typeof parts[1] === 'undefined') {
fde6ea95
JA
384 return;
385 }
312d2d7c
JA
386 t = msg.split(' ', 3);
387 nick = t[1];
54a2a4e1 388 //kiwi.gateway.kick(Tabview.getCurrentTab().name, nick, t[2]);
cdd803f6
D
389 break;
390
a3364605 391 case '/quote':
673a7c8f 392 kiwi.gateway.raw(msg.replace(/^\/quote /i, ''));
a3364605 393 break;
8343584e 394
a3364605 395 case '/me':
bb6a9775
JA
396 if (kiwi.currentPanel.isChannel) {
397 kiwi.gateway.ctcp(true, 'ACTION', tab.name, msg.substring(4), function () {
398 kiwi.currentPanel.addMsg(null, ' ', '* ' + kiwi.gateway.nick + ' ' + msg.substring(4), 'action', 'color:#555;');
399 });
400 }
401 //TODO: Queries
a3364605
JA
402 break;
403
404 case '/notice':
405 dest = parts[1];
406 msg = parts.slice(2).join(' ');
407
bb6a9775
JA
408 kiwi.gateway.notice(dest, msg, function () {
409 kiwi.front.events.onNotice({}, {nick: kiwi.gateway.nick, channel: dest, msg: msg});
410 });
a3364605
JA
411 break;
412
bb6a9775 413 /*case '/win':
a3364605 414 if (parts[1] !== undefined) {
b41a381f 415 kiwi.front.ui.windowsShow(parseInt(parts[1], 10));
a3364605 416 }
bb6a9775 417 break;*/
a3364605
JA
418
419 case '/quit':
b575fa08 420 kiwi.gateway.quit(parts.slice(1).join(' '));
f4f7781b
JA
421 break;
422
45c03116 423 case '/topic':
a3364605
JA
424 if (parts[1] === undefined) {
425 t = $('.cur_topic');
426 if (t.createTextRange) {
427 pos = t.text().length();
428 textRange = t.createTextRange();
429 textRange.collapse(true);
430 textRange.moveEnd(pos);
431 textRange.moveStart(pos);
432 textRange.select();
433 } else if (t.setSelectionRange) {
434 t.setSelectionRange(pos, pos);
435 }
436 } else {
bb6a9775
JA
437 if (kiwi.currentPanel.isChannel) {
438 kiwi.gateway.topic(kiwi.currentPanel.get("name"), msg.split(' ', 2)[1]);
439 }
aa191535 440 }
45c03116 441 break;
abb46d2d
D
442
443 case '/kiwi':
bb6a9775 444 kiwi.gateway.ctcp(true, 'KIWI', kiwi.currentPanel.get("name"), msg.substring(6));
abb46d2d
D
445 break;
446
a3c7edd4
JA
447 case '/ctcp':
448 parts = parts.slice(1);
449 dest = parts.shift();
312d2d7c 450 t = parts.shift();
a3c7edd4 451 msg = parts.join(' ');
312d2d7c
JA
452 console.log(parts);
453
bb6a9775
JA
454 kiwi.gateway.ctcp(true, t, dest, msg, function () {
455 kiwi.channels.server.addMsg(null, 'CTCP Request', '[to ' + dest + '] ' + t + ' ' + msg, 'ctcp');
456 });
a3c7edd4 457 break;
a3364605 458 default:
bb6a9775 459 kiwi.currentPanel.addMsg(null, ' ', '--> Invalid command: '+parts[0].substring(1));
8343584e 460 kiwi.gateway.raw(msg.substring(1));
bfdeb872 461 break;
a3364605
JA
462 }
463
464 } else {
465 //alert('Sending message: '+msg);
466 if (msg.trim() === '') {
bad1ea63
JA
467 return;
468 }
bb6a9775
JA
469 if (kiwi.currentPanel.isChannel) {
470 kiwi.gateway.privmsg(kiwi.currentPanel.get("name"), msg, function () {
471 kiwi.currentPanel.addMsg(null, kiwi.gateway.nick, msg);
472 });
473 }
a3364605
JA
474 }
475 },
8343584e
D
476
477
8343584e 478
8343584e 479
7af36ece 480
0b399cb0
D
481 /**
482 * Sort the window list
483 */
484 sortWindowList: function () {
f93aafe5
JA
485 var win_list = $('#kiwi .windowlist ul'),
486 listitems = win_list.children('li').get();
c32b30d6 487
54a2a4e1 488 /*listitems.sort(function (a, b) {
f93aafe5 489 if (a === Tabview.getServerTab().tab[0]) {
0b399cb0
D
490 return -1;
491 }
f93aafe5 492 if (b === Tabview.getServerTab().tab[0]) {
b16d21f2
JA
493 return 1;
494 }
f93aafe5
JA
495 var compA = $(a).text().toUpperCase(),
496 compB = $(b).text().toUpperCase();
0b399cb0 497 return (compA < compB) ? -1 : (compA > compB) ? 1 : 0;
f93aafe5 498 });
0b399cb0
D
499
500 $.each(listitems, function(idx, itm) {
501 win_list.append(itm);
54a2a4e1 502 });*/
0b399cb0
D
503 },
504
505
506
a3364605 507
5a29866a
JA
508 /**
509 * Syncs with the Kiwi server
510 * Not implemented
511 */
a3364605 512 sync: function () {
673a7c8f 513 kiwi.gateway.sync();
a3364605 514 },
8343584e 515
5a29866a
JA
516 /**
517 * Checks if a given name is the name of a channel
518 * @param {String} name The name to check
519 * @returns {Boolean} True if name is the name of a channel, false if it is not
520 */
a3364605 521 isChannel: function (name) {
c6ef62a3 522 var prefix, is_chan;
a3364605 523 prefix = name.charAt(0);
673a7c8f 524 if (kiwi.gateway.channel_prefix.indexOf(prefix) > -1) {
a3364605
JA
525 is_chan = true;
526 } else {
527 is_chan = false;
528 }
8343584e 529
a3364605
JA
530 return is_chan;
531 },
8343584e 532
5a29866a
JA
533 /**
534 * Formats a message. Adds bold, underline and colouring
535 * @param {String} msg The message to format
536 * @returns {String} The HTML formatted message
537 */
0a202119 538 formatIRCMsg: function (msg) {
8343584e
D
539 var re, next;
540
9d34a1ca 541 if ((!msg) || (typeof msg !== 'string')) {
b91949aa 542 return '';
9d34a1ca 543 }
8343584e 544
24552b4b
JA
545 // bold
546 if (msg.indexOf(String.fromCharCode(2)) !== -1) {
547 next = '<b>';
548 while (msg.indexOf(String.fromCharCode(2)) !== -1) {
549 msg = msg.replace(String.fromCharCode(2), next);
550 next = (next === '<b>') ? '</b>' : '<b>';
551 }
552 if (next === '</b>') {
553 msg = msg + '</b>';
554 }
555 }
8343584e 556
24552b4b
JA
557 // underline
558 if (msg.indexOf(String.fromCharCode(31)) !== -1) {
559 next = '<u>';
560 while (msg.indexOf(String.fromCharCode(31)) !== -1) {
561 msg = msg.replace(String.fromCharCode(31), next);
562 next = (next === '<u>') ? '</u>' : '<u>';
563 }
564 if (next === '</u>') {
565 msg = msg + '</u>';
566 }
567 }
8343584e 568
24552b4b 569 // colour
5a29866a
JA
570 /**
571 * @inner
572 */
52a45f8c
JA
573 msg = (function (msg) {
574 var replace, colourMatch, col, i, match, to, endCol, fg, bg, str;
575 replace = '';
5a29866a
JA
576 /**
577 * @inner
578 */
52a45f8c
JA
579 colourMatch = function (str) {
580 var re = /^\x03([0-9][0-5]?)(,([0-9][0-5]?))?/;
581 return re.exec(str);
582 };
5a29866a
JA
583 /**
584 * @inner
585 */
52a45f8c
JA
586 col = function (num) {
587 switch (parseInt(num, 10)) {
588 case 0:
589 return '#FFFFFF';
590 case 1:
591 return '#000000';
592 case 2:
593 return '#000080';
594 case 3:
595 return '#008000';
596 case 4:
597 return '#FF0000';
598 case 5:
599 return '#800040';
600 case 6:
601 return '#800080';
602 case 7:
603 return '#FF8040';
604 case 8:
605 return '#FFFF00';
606 case 9:
607 return '#80FF00';
608 case 10:
609 return '#008080';
610 case 11:
611 return '#00FFFF';
612 case 12:
613 return '#0000FF';
614 case 13:
615 return '#FF55FF';
616 case 14:
617 return '#808080';
618 case 15:
619 return '#C0C0C0';
620 default:
621 return null;
622 }
623 };
624 if (msg.indexOf('\x03') !== -1) {
625 i = msg.indexOf('\x03');
626 replace = msg.substr(0, i);
627 while (i < msg.length) {
5a29866a
JA
628 /**
629 * @inner
630 */
52a45f8c
JA
631 match = colourMatch(msg.substr(i, 6));
632 if (match) {
633 //console.log(match);
634 // Next colour code
635 to = msg.indexOf('\x03', i + 1);
636 endCol = msg.indexOf(String.fromCharCode(15), i + 1);
637 if (endCol !== -1) {
638 if (to === -1) {
639 to = endCol;
640 } else {
641 to = ((to < endCol) ? to : endCol);
642 }
643 }
644 if (to === -1) {
645 to = msg.length;
646 }
647 //console.log(i, to);
648 fg = col(match[1]);
649 bg = col(match[3]);
650 str = msg.substring(i + 1 + match[1].length + ((bg !== null) ? match[2].length + 1 : 0), to);
651 //console.log(str);
652 replace += '<span style="' + ((fg !== null) ? 'color: ' + fg + '; ' : '') + ((bg !== null) ? 'background-color: ' + bg + ';' : '') + '">' + str + '</span>';
653 i = to;
654 } else {
655 if ((msg[i] !== '\x03') && (msg[i] !== String.fromCharCode(15))) {
656 replace += msg[i];
657 }
658 i++;
24552b4b 659 }
52a45f8c
JA
660 }
661 return replace;
662 }
663 return msg;
664 }(msg));
665
24552b4b 666 return msg;
cbcccdbd 667 },
5a29866a
JA
668
669 /**
670 * Registers Kiwi IRC as a handler for the irc:// protocol in the browser
671 */
cbcccdbd
D
672 registerProtocolHandler: function () {
673 var state, uri;
674 url = kiwi_server.replace(/\/kiwi$/, '/?ircuri=%s');
675 try {
676 //state = window.navigator.isProtocolHandlerRegistered('irc', url);
677 //if (state !== 'registered') {
678 window.navigator.registerProtocolHandler('irc', url, 'Kiwi IRC');
679 //}
680 } catch (e) {
681 console.log('Unable to register Kiwi IRC as a handler for irc:// links');
682 console.error(e);
683 }
a3364605 684 }
8343584e 685
a3364605 686};
54f4a22e
D
687
688
689
690
691
5a29866a
JA
692/**
693* @constructor
694*/
dde5dcd9
JA
695var ChannelList = function () {
696 /*globals Utilityview */
697 var chanList, view, table, obj, renderTable, waiting;
698 chanList = [];
699
700 view = new Utilityview('Channel List');
701 view.div.css('overflow-y', 'scroll');
702
703 table = $('<table style="margin:1em 2em;"><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>');
704 table = table.appendTo(view.div);
705
706 waiting = false;
5a29866a
JA
707 /**
708 * @inner
709 */
dde5dcd9
JA
710 renderTable = function () {
711 var tbody;
712 tbody = table.children('tbody:first').detach();
713 /*tbody.children().each(function (child) {
714 var i, chan;
715 child = $(child);
716 chan = child.children('td:first').text();
717 for (i = 0; i < chanList.length; i++) {
718 if (chanList[i].channel === chan) {
719 chanList[i].html = child.detach();
720 break;
721 }
722 }
723 });*/
724 _.each(chanList, function (chan) {
725 chan.html = $(chan.html).appendTo(tbody);
726 });
727 table = table.append(tbody);
728 waiting = false;
729 };
5a29866a
JA
730 /**
731 * @lends ChannelList
732 */
733 return {
734 /**
735 * Adds a channel or channels to the list
736 * @param {Object} channels The channel or Array of channels to add
737 */
dde5dcd9
JA
738 addChannel: function (channels) {
739 if (!_.isArray(channels)) {
740 channels = [channels];
741 }
742 _.each(channels, function (chan) {
743 var html, channel;
744 html = $('<tr><td><a class="chan">' + chan.channel + '</a></td><td class="num_users" style="text-align: center;">' + chan.num_users + '</td><td style="padding-left: 2em;">' + kiwi.front.formatIRCMsg(chan.topic) + '</td></tr>');
745 chan.html = html;
746 chanList.push(chan);
747 });
748 chanList.sort(function (a, b) {
749 return b.num_users - a.num_users;
750 });
751 if (!waiting) {
752 waiting = true;
753 _.defer(renderTable);
754 }
755 },
5a29866a
JA
756 /**
757 * Show the {@link UtilityView} that will display this channel list
758 */
dde5dcd9
JA
759 show: function () {
760 view.show();
761 },
5a29866a
JA
762 /**
763 * @private
764 */
dde5dcd9
JA
765 prototype: {constructor: this}
766 };
dde5dcd9 767};
54f4a22e 768
1bb74900
D
769/*
770 * MISC VIEW
771 */
5a29866a
JA
772/**
773* @constructor
943caaef
JA
774* A tab to show non-channel and non-query windows to the user
775* @param {String} name The name of the view
5a29866a 776*/
604c5174 777var Utilityview = function (name) {
c6ef62a3
JA
778 var rand_name = randomString(15),
779 tmp_divname = 'kiwi_window_' + rand_name,
c6ef62a3 780 tmp_tabname = 'kiwi_tab_' + rand_name;
8343584e 781
604c5174
D
782 this.name = rand_name;
783 this.title = name;
784 this.topic = ' ';
4e4ca8e6 785 this.panel = $('#panel1');
1bb74900 786
4e4ca8e6
D
787 if (typeof $('.scroller', this.panel)[0] === 'undefined') {
788 this.panel.append('<div id="' + tmp_divname + '" class="messages"></div>');
789 } else {
790 $('.scroller', this.panel).append('<div id="' + tmp_divname + '" class="messages"></div>');
791 }
604c5174
D
792
793 this.tab = $('<li id="' + tmp_tabname + '">' + this.title + '</li>');
c6ef62a3 794 this.tab.click(function () {
673a7c8f 795 kiwi.front.utilityviews[rand_name.toLowerCase()].show();
604c5174
D
796 });
797 $('#kiwi .utilityviewlist ul').append(this.tab);
b41a381f 798 kiwi.front.ui.doLayoutSize();
8343584e 799
1bb74900
D
800 this.div = $('#' + tmp_divname);
801 this.div.css('overflow', 'hidden');
802
673a7c8f 803 kiwi.front.utilityviews[rand_name.toLowerCase()] = this;
1bb74900
D
804};
805
806Utilityview.prototype.name = null;
604c5174 807Utilityview.prototype.title = null;
1bb74900
D
808Utilityview.prototype.div = null;
809Utilityview.prototype.tab = null;
ca7e63ea 810Utilityview.prototype.topic = ' ';
4e4ca8e6 811Utilityview.prototype.panel = null;
943caaef
JA
812/**
813* Brings this view to the foreground
814*/
1bb74900 815Utilityview.prototype.show = function () {
4e4ca8e6 816 $('.messages', this.panel).removeClass("active");
1bb74900 817 $('#kiwi .userlist ul').removeClass("active");
2b9dcc03 818 $('#kiwi .toolbars ul li').removeClass("active");
1bb74900 819
4e4ca8e6 820 this.panel.css('overflow-y', 'hidden');
2b9dcc03 821 $('#windows').css('right', 0);
1bb74900
D
822 // Activate this tab!
823 this.div.addClass('active');
824 this.tab.addClass('active');
825
826 this.addPartImage();
827
b41a381f 828 kiwi.front.ui.setTopicText(this.topic);
673a7c8f 829 kiwi.front.cur_channel = this;
1bb74900
D
830
831 // If we're using fancy scrolling, refresh it
832 if (touch_scroll) {
833 touch_scroll.refresh();
834 }
c6ef62a3 835};
943caaef
JA
836/**
837* Sets a new panel to be this view's parent
838* @param {JQuery} new_panel The new parent
839*/
4e4ca8e6
D
840Utilityview.prototype.setPanel = function (new_panel) {
841 this.div.detach();
842 this.panel = new_panel;
843 this.panel.append(this.div);
844 this.show();
845};
943caaef
JA
846/**
847* Removes the panel from the UI and destroys its contents
848*/
1bb74900
D
849Utilityview.prototype.close = function () {
850 this.div.remove();
851 this.tab.remove();
8343584e 852
1fce4b40 853 if (Tabview.getCurrentTab() === this) {
673a7c8f 854 kiwi.front.tabviews.server.show();
1bb74900 855 }
673a7c8f 856 delete kiwi.front.utilityviews[this.name.toLowerCase()];
1bb74900 857};
943caaef
JA
858/**
859* Adds the close image to the tab
860*/
1bb74900
D
861Utilityview.prototype.addPartImage = function () {
862 this.clearPartImage();
8343584e 863
1bb74900
D
864 // We can't close this tab, so don't have the close image
865 if (this.name === 'server') {
866 return;
867 }
868
8397d902 869 var del_html = '<img src="/img/redcross.png" class="tab_part" />';
1bb74900 870 this.tab.append(del_html);
8343584e 871
1bb74900 872 $('.tab_part', this.tab).click(function () {
1fce4b40
JA
873 if (Tabview.getCurrentTab().name !== 'server') {
874 Tabview.getCurrentTab().close();
1bb74900
D
875 }
876 });
877};
943caaef
JA
878/**
879* Removes the close image from the tab
880*/
1bb74900 881Utilityview.prototype.clearPartImage = function () {
2b9dcc03 882 $('#kiwi .toolbars .tab_part').remove();
1bb74900
D
883};
884
5a29866a
JA
885/**
886* @constructor
943caaef
JA
887* Floating message box
888* @param {String} classname The CSS classname to apply to the box
5a29866a 889*/
a3364605
JA
890var Box = function (classname) {
891 this.id = randomString(10);
892 var tmp = $('<div id="' + this.id + '" class="box ' + classname + '"><div class="boxarea"></div></div>');
893 $('#kiwi').append(tmp);
894 this.box = $('#' + this.id);
895 this.content = $('#' + this.id + ' .boxarea');
8343584e 896
a3364605
JA
897 this.box.draggable({ stack: ".box" });
898 this.content.click(function () {});
899 //this.box.click(function(){ $(this)..css });
900};
901Box.prototype.create = function (name, classname) {
8343584e 902
a3364605
JA
903};
904Box.prototype.id = null;
905Box.prototype.box = null;
906Box.prototype.content = null;
907Box.prototype.destroy = function () {
908 var name;
909 this.box.remove();
673a7c8f
D
910 for (name in kiwi.front.boxes) {
911 if (kiwi.front.boxes[name].id === this.id) {
912 delete kiwi.front.boxes[name];
a3364605
JA
913 }
914 }
915};
8343584e 916Box.prototype.height = function () {
a3364605
JA
917 return this.box.height();
918};