#controlbox -> .controlbox
[KiwiIRC.git] / client / assets / dev / model_application.js
1 _kiwi.model.Application = function () {
2 // Set to a reference to this object within initialize()
3 var that = null;
4
5 // The auto connect details entered into the server select box
6 var auto_connect_details = {};
7
8
9 var model = function () {
10 /** _kiwi.view.Application */
11 this.view = null;
12
13 /** _kiwi.view.StatusMessage */
14 this.message = null;
15
16 /* Address for the kiwi server */
17 this.kiwi_server = null;
18
19 this.initialize = function (options) {
20 that = this;
21
22 if (options[0].container) {
23 this.set('container', options[0].container);
24 }
25
26 // The base url to the kiwi server
27 this.set('base_path', options[0].base_path ? options[0].base_path : '/kiwi');
28
29 // Any options sent down from the server
30 this.server_settings = options[0].server_settings || {};
31
32 // Best guess at where the kiwi server is
33 this.detectKiwiServer();
34
35 // Takes instances of model_network
36 this.connections = new _kiwi.model.NetworkPanelList();
37 };
38
39
40 this.start = function () {
41 // Only debug if set in the querystring
42 if (!getQueryVariable('debug')) {
43 manageDebug(false);
44 } else {
45 //manageDebug(true);
46 }
47
48 // Set the gateway up
49 _kiwi.gateway = new _kiwi.model.Gateway();
50 this.bindGatewayCommands(_kiwi.gateway);
51
52 this.initializeClient();
53 this.initializeGlobals();
54
55 this.view.barsHide(true);
56
57 this.showIntialConenctionDialog();
58 };
59
60
61 this.detectKiwiServer = function () {
62 // If running from file, default to localhost:7777 by default
63 if (window.location.protocol === 'file:') {
64 this.kiwi_server = 'http://localhost:7778';
65 } else {
66 // Assume the kiwi server is on the same server
67 this.kiwi_server = window.location.protocol + '//' + window.location.host;
68 }
69 };
70
71
72 this.showIntialConenctionDialog = function() {
73 var connection_dialog = new _kiwi.model.NewConnection();
74 this.populateDefaultServerSettings(connection_dialog);
75
76 connection_dialog.view.$el.addClass('initial');
77 this.view.$el.find('.panel_container:first').append(connection_dialog.view.$el);
78
79 var $info = $($('#tmpl_new_connection_info').html());
80
81 if ($info.html()) {
82 connection_dialog.view.infoBoxSet($info);
83 connection_dialog.view.infoBoxShow();
84 }
85
86 // TODO: Shouldn't really be here but it's not working in the view.. :/
87 // Hack for firefox browers: Focus is not given on this event loop iteration
88 setTimeout(function(){
89 connection_dialog.view.$el.find('.nick').select();
90 }, 0);
91
92 // Once connected, close this dialog and remove its own event
93 var fn = function() {
94 connection_dialog.view.$el.slideUp(function() {
95 connection_dialog.view.dispose();
96 connection_dialog = null;
97
98 _kiwi.gateway.off('onconnect', fn);
99 });
100
101 };
102 _kiwi.gateway.on('onconnect', fn);
103 };
104
105
106 this.initializeClient = function () {
107 this.view = new _kiwi.view.Application({model: this, el: this.get('container')});
108
109 // Applets panel list
110 this.applet_panels = new _kiwi.model.PanelList();
111 this.applet_panels.view.$el.addClass('panellist applets');
112 this.view.$el.find('.tabs').append(this.applet_panels.view.$el);
113
114 /**
115 * Set the UI components up
116 */
117 this.controlbox = new _kiwi.view.ControlBox({el: $('#kiwi .controlbox')[0]});
118 this.bindControllboxCommands(this.controlbox);
119
120 this.topicbar = new _kiwi.view.TopicBar({el: this.view.$el.find('.topic')[0]});
121
122 new _kiwi.view.AppToolbar({el: _kiwi.app.view.$el.find('.toolbar .app_tools')[0]});
123
124 this.message = new _kiwi.view.StatusMessage({el: this.view.$el.find('.status_message')[0]});
125
126 this.resize_handle = new _kiwi.view.ResizeHandler({el: this.view.$el.find('.memberlists_resize_handle')[0]});
127
128 // Rejigg the UI sizes
129 this.view.doLayout();
130 };
131
132
133 this.initializeGlobals = function () {
134 _kiwi.global.connections = this.connections;
135
136 _kiwi.global.panels = this.panels;
137 _kiwi.global.panels.applets = this.applet_panels;
138
139 _kiwi.global.components.Applet = _kiwi.model.Applet;
140 _kiwi.global.components.Panel =_kiwi.model.Panel;
141 };
142
143
144 this.populateDefaultServerSettings = function (new_connection_dialog) {
145 var parts;
146 var defaults = {
147 nick: '',
148 server: '',
149 port: 6667,
150 ssl: false,
151 channel: '#chat',
152 channel_key: ''
153 };
154 var uricheck;
155
156
157 /**
158 * Get any settings set by the server
159 * These settings may be changed in the server selection dialog or via URL parameters
160 */
161 if (this.server_settings.client) {
162 if (this.server_settings.client.nick)
163 defaults.nick = this.server_settings.client.nick;
164
165 if (this.server_settings.client.server)
166 defaults.server = this.server_settings.client.server;
167
168 if (this.server_settings.client.port)
169 defaults.port = this.server_settings.client.port;
170
171 if (this.server_settings.client.ssl)
172 defaults.ssl = this.server_settings.client.ssl;
173
174 if (this.server_settings.client.channel)
175 defaults.channel = this.server_settings.client.channel;
176 }
177
178
179
180 /**
181 * Get any settings passed in the URL
182 * These settings may be changed in the server selection dialog
183 */
184
185 // Any query parameters first
186 if (getQueryVariable('nick'))
187 defaults.nick = getQueryVariable('nick');
188
189 if (window.location.hash)
190 defaults.channel = window.location.hash;
191
192
193 // Process the URL part by part, extracting as we go
194 parts = window.location.pathname.toString().replace(this.get('base_path'), '').split('/');
195
196 if (parts.length > 0) {
197 parts.shift();
198
199 if (parts.length > 0 && parts[0]) {
200 // Check to see if we're dealing with an irc: uri, or whether we need to extract the server/channel info from the HTTP URL path.
201 uricheck = parts[0].substr(0, 7).toLowerCase();
202 if ((uricheck === 'ircs%3a') || (uricheck.substr(0,6) === 'irc%3a')) {
203 parts[0] = decodeURIComponent(parts[0]);
204 // irc[s]://<host>[:<port>]/[<channel>[?<password>]]
205 uricheck = /^irc(s)?:(?:\/\/?)?([^:\/]+)(?::([0-9]+))?(?:(?:\/)([^\?]*)(?:(?:\?)(.*))?)?$/.exec(parts[0]);
206 /*
207 uricheck[1] = ssl (optional)
208 uricheck[2] = host
209 uricheck[3] = port (optional)
210 uricheck[4] = channel (optional)
211 uricheck[5] = channel key (optional, channel must also be set)
212 */
213 if (uricheck) {
214 if (typeof uricheck[1] !== 'undefined') {
215 defaults.ssl = true;
216 if (defaults.port === 6667) {
217 defaults.port = 6697;
218 }
219 }
220 defaults.server = uricheck[2];
221 if (typeof uricheck[3] !== 'undefined') {
222 defaults.port = uricheck[3];
223 }
224 if (typeof uricheck[4] !== 'undefined') {
225 defaults.channel = '#' + uricheck[4];
226 if (typeof uricheck[5] !== 'undefined') {
227 defaults.channel_key = uricheck[5];
228 }
229 }
230 }
231 parts = [];
232 } else {
233 // Extract the port+ssl if we find one
234 if (parts[0].search(/:/) > 0) {
235 defaults.port = parts[0].substring(parts[0].search(/:/) + 1);
236 defaults.server = parts[0].substring(0, parts[0].search(/:/));
237 if (defaults.port[0] === '+') {
238 defaults.port = parseInt(defaults.port.substring(1), 10);
239 defaults.ssl = true;
240 } else {
241 defaults.ssl = false;
242 }
243
244 } else {
245 defaults.server = parts[0];
246 }
247
248 parts.shift();
249 }
250 }
251
252 if (parts.length > 0 && parts[0]) {
253 defaults.channel = '#' + parts[0];
254 parts.shift();
255 }
256 }
257
258 // If any settings have been given by the server.. override any auto detected settings
259 /**
260 * Get any server restrictions as set in the server config
261 * These settings can not be changed in the server selection dialog
262 */
263 if (this.server_settings && this.server_settings.connection) {
264 if (this.server_settings.connection.server) {
265 defaults.server = this.server_settings.connection.server;
266 }
267
268 if (this.server_settings.connection.port) {
269 defaults.port = this.server_settings.connection.port;
270 }
271
272 if (this.server_settings.connection.ssl) {
273 defaults.ssl = this.server_settings.connection.ssl;
274 }
275
276 if (this.server_settings.connection.channel) {
277 defaults.channel = this.server_settings.connection.channel;
278 }
279
280 if (this.server_settings.connection.nick) {
281 defaults.nick = this.server_settings.connection.nick;
282 }
283 }
284
285 // Set any random numbers if needed
286 defaults.nick = defaults.nick.replace('?', Math.floor(Math.random() * 100000).toString());
287
288 // Populate the server select box with defaults
289 new_connection_dialog.view.populateFields(defaults);
290 };
291
292
293 this.panels = (function() {
294 var fn = function(panel_type) {
295 var panels;
296
297 // Default panel type
298 panel_type = panel_type || 'connections';
299
300 switch (panel_type) {
301 case 'connections':
302 panels = this.connections.panels();
303 break;
304 case 'applets':
305 panels = this.applet_panels.models;
306 break;
307 }
308
309 // Active panels / server
310 panels.active = this.connections.active_panel;
311 panels.server = this.connections.active_connection ?
312 this.connections.active_connection.panels.server :
313 null;
314
315 return panels;
316 };
317
318 _.extend(fn, Backbone.Events);
319
320 return fn;
321 })();
322
323
324 this.bindGatewayCommands = function (gw) {
325 gw.on('onconnect', function (event) {
326 that.view.barsShow();
327
328 if (auto_connect_details.channel) {
329 that.controlbox.processInput('/JOIN ' + auto_connect_details.channel + ' ' + auto_connect_details.channel_key);
330 }
331 });
332
333
334 (function () {
335 var gw_stat = 0;
336
337 gw.on('disconnect', function (event) {
338 var msg = 'You have been disconnected. Attempting to reconnect for you..';
339 that.message.text(msg, {timeout: 10000});
340
341 that.view.$el.removeClass('connected');
342
343 // Mention the disconnection on every channel
344 $.each(_kiwi.app.connections.getByConnectionId(0).panels.models, function (idx, panel) {
345 if (!panel || !panel.isChannel()) return;
346 panel.addMsg('', msg, 'action quit');
347 });
348 _kiwi.app.connections.getByConnectionId(0).panels.server.addMsg('', msg, 'action quit');
349
350 gw_stat = 1;
351 });
352 gw.on('reconnecting', function (event) {
353 msg = 'You have been disconnected. Attempting to reconnect again in ' + (event.delay/1000) + ' seconds..';
354 _kiwi.app.connections.getByConnectionId(0).panels.server.addMsg('', msg, 'action quit');
355 });
356 gw.on('onconnect', function (event) {
357 that.view.$el.addClass('connected');
358 if (gw_stat !== 1) return;
359
360 var msg = 'It\'s OK, you\'re connected again :)';
361 that.message.text(msg, {timeout: 5000});
362
363 // Mention the disconnection on every channel
364 $.each(_kiwi.app.connections.getByConnectionId(0).panels.models, function (idx, panel) {
365 if (!panel || !panel.isChannel()) return;
366 panel.addMsg('', msg, 'action join');
367 });
368 _kiwi.app.connections.getByConnectionId(0).panels.server.addMsg('', msg, 'action join');
369
370 gw_stat = 0;
371 });
372 })();
373
374 };
375
376
377
378 /**
379 * Bind to certain commands that may be typed into the control box
380 */
381 this.bindControllboxCommands = function (controlbox) {
382 // Default aliases
383 $.extend(controlbox.preprocessor.aliases, {
384 // General aliases
385 '/p': '/part $1+',
386 '/me': '/action $1+',
387 '/j': '/join $1+',
388 '/q': '/query $1+',
389
390 // Op related aliases
391 '/op': '/quote mode $channel +o $1+',
392 '/deop': '/quote mode $channel -o $1+',
393 '/hop': '/quote mode $channel +h $1+',
394 '/dehop': '/quote mode $channel -h $1+',
395 '/voice': '/quote mode $channel +v $1+',
396 '/devoice': '/quote mode $channel -v $1+',
397 '/k': '/kick $channel $1+',
398
399 // Misc aliases
400 '/slap': '/me slaps $1 around a bit with a large trout'
401 });
402
403 controlbox.on('unknown_command', unknownCommand);
404
405 controlbox.on('command', allCommands);
406 controlbox.on('command:msg', msgCommand);
407
408 controlbox.on('command:action', actionCommand);
409
410 controlbox.on('command:join', joinCommand);
411
412 controlbox.on('command:part', partCommand);
413
414 controlbox.on('command:nick', function (ev) {
415 _kiwi.gateway.changeNick(null, ev.params[0]);
416 });
417
418 controlbox.on('command:query', queryCommand);
419
420 controlbox.on('command:topic', topicCommand);
421
422 controlbox.on('command:notice', noticeCommand);
423
424 controlbox.on('command:quote', quoteCommand);
425
426 controlbox.on('command:kick', kickCommand);
427
428 controlbox.on('command:clear', clearCommand);
429
430 controlbox.on('command:ctcp', ctcpCommand);
431
432 controlbox.on('command:server', serverCommand);
433
434
435 controlbox.on('command:css', function (ev) {
436 var queryString = '?reload=' + new Date().getTime();
437 $('link[rel="stylesheet"]').each(function () {
438 this.href = this.href.replace(/\?.*|$/, queryString);
439 });
440 });
441
442 controlbox.on('command:js', function (ev) {
443 if (!ev.params[0]) return;
444 $script(ev.params[0] + '?' + (new Date().getTime()));
445 });
446
447
448 controlbox.on('command:set', function (ev) {
449 if (!ev.params[0]) return;
450
451 var setting = ev.params[0],
452 value;
453
454 // Do we have a second param to set a value?
455 if (ev.params[1]) {
456 ev.params.shift();
457
458 value = ev.params.join(' ');
459
460 // If we're setting a true boolean value..
461 if (value === 'true')
462 value = true;
463
464 // If we're setting a false boolean value..
465 if (value === 'false')
466 value = false;
467
468 // If we're setting a number..
469 if (parseInt(value, 10).toString() === value)
470 value = parseInt(value, 10);
471
472 _kiwi.global.settings.set(setting, value);
473 }
474
475 // Read the value to the user
476 _kiwi.app.panels().active.addMsg('', setting + ' = ' + _kiwi.global.settings.get(setting).toString());
477 });
478
479
480 controlbox.on('command:save', function (ev) {
481 _kiwi.global.settings.save();
482 _kiwi.app.panels().active.addMsg('', 'Settings have been saved');
483 });
484
485
486 controlbox.on('command:alias', function (ev) {
487 var name, rule;
488
489 // No parameters passed so list them
490 if (!ev.params[1]) {
491 $.each(controlbox.preprocessor.aliases, function (name, rule) {
492 _kiwi.app.panels().server.addMsg(' ', name + ' => ' + rule);
493 });
494 return;
495 }
496
497 // Deleting an alias?
498 if (ev.params[0] === 'del' || ev.params[0] === 'delete') {
499 name = ev.params[1];
500 if (name[0] !== '/') name = '/' + name;
501 delete controlbox.preprocessor.aliases[name];
502 return;
503 }
504
505 // Add the alias
506 name = ev.params[0];
507 ev.params.shift();
508 rule = ev.params.join(' ');
509
510 // Make sure the name starts with a slash
511 if (name[0] !== '/') name = '/' + name;
512
513 // Now actually add the alias
514 controlbox.preprocessor.aliases[name] = rule;
515 });
516
517
518 controlbox.on('command:ignore', function (ev) {
519 var list = _kiwi.gateway.get('ignore_list');
520
521 // No parameters passed so list them
522 if (!ev.params[0]) {
523 if (list.length > 0) {
524 _kiwi.app.panels().active.addMsg(' ', 'Ignored nicks:');
525 $.each(list, function (idx, ignored_pattern) {
526 _kiwi.app.panels().active.addMsg(' ', ignored_pattern);
527 });
528 } else {
529 _kiwi.app.panels().active.addMsg(' ', 'Not ignoring anybody');
530 }
531 return;
532 }
533
534 // We have a parameter, so add it
535 list.push(ev.params[0]);
536 _kiwi.gateway.set('ignore_list', list);
537 _kiwi.app.panels().active.addMsg(' ', 'Ignoring ' + ev.params[0]);
538 });
539
540
541 controlbox.on('command:unignore', function (ev) {
542 var list = _kiwi.gateway.get('ignore_list');
543
544 if (!ev.params[0]) {
545 _kiwi.app.panels().active.addMsg(' ', 'Specifiy which nick you wish to stop ignoring');
546 return;
547 }
548
549 list = _.reject(list, function(pattern) {
550 return pattern === ev.params[0];
551 });
552
553 _kiwi.gateway.set('ignore_list', list);
554
555 _kiwi.app.panels().active.addMsg(' ', 'Stopped ignoring ' + ev.params[0]);
556 });
557
558
559 controlbox.on('command:applet', appletCommand);
560 controlbox.on('command:settings', settingsCommand);
561 controlbox.on('command:script', scriptCommand);
562 };
563
564 // A fallback action. Send a raw command to the server
565 function unknownCommand (ev) {
566 var raw_cmd = ev.command + ' ' + ev.params.join(' ');
567 console.log('RAW: ' + raw_cmd);
568 _kiwi.gateway.raw(null, raw_cmd);
569 }
570
571 function allCommands (ev) {}
572
573 function joinCommand (ev) {
574 var panels, channel_names;
575
576 channel_names = ev.params.join(' ').split(',');
577 panels = that.connections.active_connection.createAndJoinChannels(channel_names);
578
579 // Show the last channel if we have one
580 if (panels)
581 panels[panels.length - 1].view.show();
582 }
583
584 function queryCommand (ev) {
585 var destination, panel;
586
587 destination = ev.params[0];
588
589 // Check if we have the panel already. If not, create it
590 panel = that.connections.active_connection.panels.getByName(destination);
591 if (!panel) {
592 panel = new _kiwi.model.Query({name: destination});
593 that.connections.active_connection.panels.add(panel);
594 }
595
596 if (panel) panel.view.show();
597
598 }
599
600 function msgCommand (ev) {
601 var destination = ev.params[0],
602 panel = that.connections.active_connection.panels.getByName(destination) || that.panels().server;
603
604 ev.params.shift();
605
606 panel.addMsg(_kiwi.app.connections.active_connection.get('nick'), ev.params.join(' '));
607 _kiwi.gateway.privmsg(null, destination, ev.params.join(' '));
608 }
609
610 function actionCommand (ev) {
611 if (_kiwi.app.panels().active.isServer()) {
612 return;
613 }
614
615 var panel = _kiwi.app.panels().active;
616 panel.addMsg('', '* ' + _kiwi.app.connections.active_connection.get('nick') + ' ' + ev.params.join(' '), 'action');
617 _kiwi.gateway.action(null, panel.get('name'), ev.params.join(' '));
618 }
619
620 function partCommand (ev) {
621 if (ev.params.length === 0) {
622 _kiwi.gateway.part(null, _kiwi.app.panels().active.get('name'));
623 } else {
624 _.each(ev.params, function (channel) {
625 _kiwi.gateway.part(null, channel);
626 });
627 }
628 }
629
630 function topicCommand (ev) {
631 var channel_name;
632
633 if (ev.params.length === 0) return;
634
635 if (that.isChannelName(ev.params[0])) {
636 channel_name = ev.params[0];
637 ev.params.shift();
638 } else {
639 channel_name = _kiwi.app.panels().active.get('name');
640 }
641
642 _kiwi.gateway.topic(null, channel_name, ev.params.join(' '));
643 }
644
645 function noticeCommand (ev) {
646 var destination;
647
648 // Make sure we have a destination and some sort of message
649 if (ev.params.length <= 1) return;
650
651 destination = ev.params[0];
652 ev.params.shift();
653
654 _kiwi.gateway.notice(null, destination, ev.params.join(' '));
655 }
656
657 function quoteCommand (ev) {
658 var raw = ev.params.join(' ');
659 _kiwi.gateway.raw(null, raw);
660 }
661
662 function kickCommand (ev) {
663 var nick, panel = _kiwi.app.panels().active;
664
665 if (!panel.isChannel()) return;
666
667 // Make sure we have a nick
668 if (ev.params.length === 0) return;
669
670 nick = ev.params[0];
671 ev.params.shift();
672
673 _kiwi.gateway.kick(null, panel.get('name'), nick, ev.params.join(' '));
674 }
675
676 function clearCommand (ev) {
677 // Can't clear a server or applet panel
678 if (_kiwi.app.panels().active.isServer() || _kiwi.app.panels().active.isApplet()) {
679 return;
680 }
681
682 if (_kiwi.app.panels().active.clearMessages) {
683 _kiwi.app.panels().active.clearMessages();
684 }
685 }
686
687 function ctcpCommand(ev) {
688 var target, type;
689
690 // Make sure we have a target and a ctcp type (eg. version, time)
691 if (ev.params.length < 2) return;
692
693 target = ev.params[0];
694 ev.params.shift();
695
696 type = ev.params[0];
697 ev.params.shift();
698
699 _kiwi.gateway.ctcp(null, true, type, target, ev.params.join(' '));
700 }
701
702 function settingsCommand (ev) {
703 var settings = _kiwi.model.Applet.loadOnce('kiwi_settings');
704 settings.view.show();
705 }
706
707 function scriptCommand (ev) {
708 var editor = _kiwi.model.Applet.loadOnce('kiwi_script_editor');
709 editor.view.show();
710 }
711
712 function appletCommand (ev) {
713 if (!ev.params[0]) return;
714
715 var panel = new _kiwi.model.Applet();
716
717 if (ev.params[1]) {
718 // Url and name given
719 panel.load(ev.params[0], ev.params[1]);
720 } else {
721 // Load a pre-loaded applet
722 if (_kiwi.applets[ev.params[0]]) {
723 panel.load(new _kiwi.applets[ev.params[0]]());
724 } else {
725 _kiwi.app.panels().server.addMsg('', 'Applet "' + ev.params[0] + '" does not exist');
726 return;
727 }
728 }
729
730 _kiwi.app.connections.active_connection.panels.add(panel);
731 panel.view.show();
732 }
733
734
735 function serverCommand (ev) {
736 var server, port, ssl, password, nick,
737 tmp;
738
739 // If no server address given, show the new connection dialog
740 if (!ev.params[0]) {
741 tmp = new _kiwi.view.MenuBox('New Connection');
742 tmp.addItem('new_connection', new _kiwi.model.NewConnection().view.$el);
743 tmp.show();
744
745 // Center screen the dialog
746 tmp.$el.offset({
747 top: (that.view.$el.height() / 2) - (tmp.$el.height() / 2),
748 left: (that.view.$el.width() / 2) - (tmp.$el.width() / 2)
749 });
750
751 return;
752 }
753
754 // Port given in 'host:port' format and no specific port given after a space
755 if (ev.params[0].indexOf(':') > 0) {
756 tmp = ev.params[0].split(':');
757 server = tmp[0];
758 port = tmp[1];
759
760 password = ev.params[1] || undefined;
761
762 } else {
763 // Server + port given as 'host port'
764 server = ev.params[0];
765 port = ev.params[1] || 6667;
766
767 password = ev.params[2] || undefined;
768 }
769
770 // + in the port means SSL
771 if (port.toString()[0] === '+') {
772 ssl = true;
773 port = parseInt(port.substring(1), 10);
774 } else {
775 ssl = false;
776 }
777
778 // Default port if one wasn't found
779 port = port || 6667;
780
781 // Use the same nick as we currently have
782 nick = _kiwi.app.connections.active_connection.get('nick');
783
784 _kiwi.app.panels().active.addMsg('', 'Connecting to ' + server + ':' + port.toString() + '..');
785
786 _kiwi.gateway.newConnection({
787 nick: nick,
788 host: server,
789 port: port,
790 ssl: ssl,
791 password: password
792 }, function(err, new_connection) {
793 if (err)
794 _kiwi.app.panels().active.addMsg('', 'Error connecting to ' + server + ':' + port.toString() + ' (' + err.toString() + ')');
795 });
796 }
797
798
799
800
801
802 this.isChannelName = function (channel_name) {
803 var channel_prefix = _kiwi.gateway.get('channel_prefix');
804
805 if (!channel_name || !channel_name.length) return false;
806 return (channel_prefix.indexOf(channel_name[0]) > -1);
807 };
808
809
810 };
811
812
813 model = Backbone.Model.extend(new model());
814
815 return new model(arguments);
816 };