Server side PluginInterface ported into the browser
[KiwiIRC.git] / client / src / app.js
CommitLineData
eaaf73b0 1// Holds anything kiwi client specific (ie. front, gateway, _kiwi.plugs..)\r
9df70c63
D
2/**\r
3* @namespace\r
4*/\r
eaaf73b0 5var _kiwi = {};\r
9df70c63 6\r
eaaf73b0
D
7_kiwi.model = {};\r
8_kiwi.view = {};\r
9_kiwi.applets = {};\r
b62c8381
D
10\r
11\r
12/**\r
13 * A global container for third party access\r
14 * Will be used to access a limited subset of kiwi functionality\r
15 * and data (think: plugins)\r
16 */\r
eaaf73b0 17_kiwi.global = {\r
4c424593 18 build_version: '', // Kiwi IRC version this is built from (Set from index.html)\r
161b5673 19 settings: undefined, // Instance of _kiwi.model.DataStore\r
2a89ba11
D
20 plugins: undefined, // Instance of _kiwi.model.PluginManager\r
21 events: undefined, // Instance of PluginInterface\r
eec9e67d 22 utils: {}, // TODO: Re-usable methods\r
161b5673 23\r
f1452889
D
24 addMediaMessageType: function(match, buildHtml) {\r
25 _kiwi.view.MediaMessage.addType(match, buildHtml);\r
26 },\r
27\r
161b5673
D
28 // Event managers for plugins\r
29 components: {\r
30 EventComponent: function(event_source, proxy_event_name) {\r
31 function proxyEvent(event_name, event_data) {\r
32 if (proxy_event_name !== 'all') {\r
33 event_data = event_name.event_data;\r
f1452889 34 event_name = event_name.event_name;\r
161b5673 35 }\r
f1452889 36\r
161b5673
D
37 this.trigger(event_name, event_data);\r
38 }\r
39\r
40 // The event we are to proxy\r
41 proxy_event_name = proxy_event_name || 'all';\r
42\r
43\r
44 _.extend(this, Backbone.Events);\r
45 this._source = event_source;\r
46\r
47 // Proxy the events to this dispatcher\r
48 event_source.on(proxy_event_name, proxyEvent, this);\r
49\r
50 // Clean up this object\r
51 this.dispose = function () {\r
52 event_source.off(proxy_event_name, proxyEvent);\r
53 this.off();\r
54 delete this.event_source;\r
55 };\r
56 },\r
57\r
58 Network: function(connection_id) {\r
59 var connection_event;\r
60\r
61 if (typeof connection_id !== 'undefined') {\r
62 connection_event = 'connection:' + connection_id.toString();\r
63 }\r
64\r
65 var obj = new this.EventComponent(_kiwi.gateway, connection_event);\r
66 var funcs = {\r
67 kiwi: 'kiwi', raw: 'raw', kick: 'kick', topic: 'topic',\r
68 part: 'part', join: 'join', action: 'action', ctcp: 'ctcp',\r
9de52d29 69 ctcpRequest: 'ctcpRequest', ctcpResponse: 'ctcpResponse',\r
72db27e4
D
70 notice: 'notice', msg: 'privmsg', changeNick: 'changeNick',\r
71 channelInfo: 'channelInfo', mode: 'mode'\r
161b5673
D
72 };\r
73\r
74 // Proxy each gateway method\r
75 _.each(funcs, function(gateway_fn, func_name) {\r
76 obj[func_name] = function() {\r
77 var fn_name = gateway_fn;\r
78\r
79 // Add connection_id to the argument list\r
80 var args = Array.prototype.slice.call(arguments, 0);\r
81 args.unshift(connection_id);\r
82\r
83 // Call the gateway function on behalf of this connection\r
84 return _kiwi.gateway[fn_name].apply(_kiwi.gateway, args);\r
85 };\r
86 });\r
87\r
88 return obj;\r
89 },\r
90\r
91 ControlInput: function() {\r
92 var obj = new this.EventComponent(_kiwi.app.controlbox);\r
93 var funcs = {\r
d63a5832 94 run: 'processInput', addPluginIcon: 'addPluginIcon'\r
161b5673
D
95 };\r
96\r
97 _.each(funcs, function(controlbox_fn, func_name) {\r
98 obj[func_name] = function() {\r
99 var fn_name = controlbox_fn;\r
100 return _kiwi.app.controlbox[fn_name].apply(_kiwi.app.controlbox, arguments);\r
101 };\r
102 });\r
103\r
104 return obj;\r
105 }\r
106 },\r
107\r
108 // Entry point to start the kiwi application\r
6b8fbed0 109 init: function (opts, callback) {\r
c3d988bc 110 var jobs, locale, localeLoaded, textThemeLoaded, text_theme;\r
161b5673 111 opts = opts || {};\r
b62c8381 112\r
28990b2a 113 jobs = new JobManager();\r
c3d988bc 114 jobs.onFinish(function(locale, s, xhr) {\r
161b5673 115 _kiwi.app = new _kiwi.model.Application(opts);\r
0fa2ca42 116\r
161b5673 117 // Start the client up\r
6b8fbed0 118 _kiwi.app.initializeInterfaces();\r
62c18d2d 119\r
2a89ba11
D
120 // Event emitter to let plugins interface with parts of kiwi\r
121 _kiwi.global.events = new PluginInterface();\r
122\r
f66c4823
D
123 // Now everything has started up, load the plugin manager for third party plugins\r
124 _kiwi.global.plugins = new _kiwi.model.PluginManager();\r
125\r
c3d988bc
D
126 callback();\r
127 });\r
28990b2a 128\r
c3d988bc
D
129 textThemeLoaded = function(text_theme, s, xhr) {\r
130 opts.text_theme = text_theme;\r
28990b2a
D
131\r
132 jobs.finishJob('load_text_theme');\r
133 };\r
0fa2ca42 134\r
c3d988bc
D
135 localeLoaded = function(locale, s, xhr) {\r
136 if (locale) {\r
137 _kiwi.global.i18n = new Jed(locale);\r
138 } else {\r
139 _kiwi.global.i18n = new Jed();\r
140 }\r
141\r
142 jobs.finishJob('load_locale');\r
143 };\r
144\r
f66c4823
D
145 // Set up the settings datastore\r
146 _kiwi.global.settings = _kiwi.model.DataStore.instance('kiwi.settings');\r
147 _kiwi.global.settings.load();\r
148\r
d26a40c6 149 // Set the window title\r
2df39a5c 150 window.document.title = opts.server_settings.client.window_title || 'Kiwi IRC';\r
d26a40c6 151\r
28990b2a 152 jobs.registerJob('load_locale');\r
19c790f1 153 locale = _kiwi.global.settings.get('locale');\r
0fa2ca42 154 if (!locale) {\r
c3d988bc 155 $.getJSON(opts.base_path + '/assets/locales/magic.json', localeLoaded);\r
0fa2ca42 156 } else {\r
c3d988bc 157 $.getJSON(opts.base_path + '/assets/locales/' + locale + '.json', localeLoaded);\r
0fa2ca42 158 }\r
d2cf53f5 159\r
28990b2a 160 jobs.registerJob('load_text_theme');\r
3a146f27
D
161 text_theme = opts.server_settings.client.settings.text_theme || 'default';\r
162 $.getJSON(opts.base_path + '/assets/text_themes/' + text_theme + '.json', textThemeLoaded);\r
6b8fbed0
D
163 },\r
164\r
165 start: function() {\r
166 _kiwi.app.showStartup();\r
167 },\r
168\r
169 // Allow plugins to change the startup applet\r
170 registerStartupApplet: function(startup_applet_name) {\r
171 _kiwi.app.startup_applet_name = startup_applet_name;\r
e537d683
D
172 },\r
173\r
174 /**\r
175 * Open a new IRC connection\r
176 * @param {Object} connection_details {nick, host, port, ssl, password, options}\r
177 * @param {Function} callback function(err, network){}\r
178 */\r
179 newIrcConnection: function(connection_details, callback) {\r
180 _kiwi.gateway.newConnection(connection_details, callback);\r
d0734219
D
181 },\r
182\r
183\r
184 /**\r
185 * Taking settings from the server and URL, extract the default server/channel/nick settings\r
186 */\r
187 defaultServerSettings: function () {\r
188 var parts;\r
189 var defaults = {\r
190 nick: '',\r
191 server: '',\r
192 port: 6667,\r
193 ssl: false,\r
194 channel: '',\r
195 channel_key: ''\r
196 };\r
197 var uricheck;\r
198\r
199\r
200 /**\r
201 * Get any settings set by the server\r
202 * These settings may be changed in the server selection dialog or via URL parameters\r
203 */\r
204 if (_kiwi.app.server_settings.client) {\r
205 if (_kiwi.app.server_settings.client.nick)\r
206 defaults.nick = _kiwi.app.server_settings.client.nick;\r
207\r
208 if (_kiwi.app.server_settings.client.server)\r
209 defaults.server = _kiwi.app.server_settings.client.server;\r
210\r
211 if (_kiwi.app.server_settings.client.port)\r
212 defaults.port = _kiwi.app.server_settings.client.port;\r
213\r
214 if (_kiwi.app.server_settings.client.ssl)\r
215 defaults.ssl = _kiwi.app.server_settings.client.ssl;\r
216\r
217 if (_kiwi.app.server_settings.client.channel)\r
218 defaults.channel = _kiwi.app.server_settings.client.channel;\r
219\r
220 if (_kiwi.app.server_settings.client.channel_key)\r
221 defaults.channel_key = _kiwi.app.server_settings.client.channel_key;\r
222 }\r
223\r
224\r
225\r
226 /**\r
227 * Get any settings passed in the URL\r
228 * These settings may be changed in the server selection dialog\r
229 */\r
230\r
231 // Any query parameters first\r
232 if (getQueryVariable('nick'))\r
233 defaults.nick = getQueryVariable('nick');\r
234\r
235 if (window.location.hash)\r
236 defaults.channel = window.location.hash;\r
237\r
238\r
239 // Process the URL part by part, extracting as we go\r
240 parts = window.location.pathname.toString().replace(_kiwi.app.get('base_path'), '').split('/');\r
241\r
242 if (parts.length > 0) {\r
243 parts.shift();\r
244\r
245 if (parts.length > 0 && parts[0]) {\r
246 // 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.\r
247 uricheck = parts[0].substr(0, 7).toLowerCase();\r
248 if ((uricheck === 'ircs%3a') || (uricheck.substr(0,6) === 'irc%3a')) {\r
249 parts[0] = decodeURIComponent(parts[0]);\r
250 // irc[s]://<host>[:<port>]/[<channel>[?<password>]]\r
251 uricheck = /^irc(s)?:(?:\/\/?)?([^:\/]+)(?::([0-9]+))?(?:(?:\/)([^\?]*)(?:(?:\?)(.*))?)?$/.exec(parts[0]);\r
252 /*\r
253 uricheck[1] = ssl (optional)\r
254 uricheck[2] = host\r
255 uricheck[3] = port (optional)\r
256 uricheck[4] = channel (optional)\r
257 uricheck[5] = channel key (optional, channel must also be set)\r
258 */\r
259 if (uricheck) {\r
260 if (typeof uricheck[1] !== 'undefined') {\r
261 defaults.ssl = true;\r
262 if (defaults.port === 6667) {\r
263 defaults.port = 6697;\r
264 }\r
265 }\r
266 defaults.server = uricheck[2];\r
267 if (typeof uricheck[3] !== 'undefined') {\r
268 defaults.port = uricheck[3];\r
269 }\r
270 if (typeof uricheck[4] !== 'undefined') {\r
271 defaults.channel = '#' + uricheck[4];\r
272 if (typeof uricheck[5] !== 'undefined') {\r
273 defaults.channel_key = uricheck[5];\r
274 }\r
275 }\r
276 }\r
277 parts = [];\r
278 } else {\r
279 // Extract the port+ssl if we find one\r
280 if (parts[0].search(/:/) > 0) {\r
281 defaults.port = parts[0].substring(parts[0].search(/:/) + 1);\r
282 defaults.server = parts[0].substring(0, parts[0].search(/:/));\r
283 if (defaults.port[0] === '+') {\r
284 defaults.port = parseInt(defaults.port.substring(1), 10);\r
285 defaults.ssl = true;\r
286 } else {\r
287 defaults.ssl = false;\r
288 }\r
289\r
290 } else {\r
291 defaults.server = parts[0];\r
292 }\r
293\r
294 parts.shift();\r
295 }\r
296 }\r
297\r
298 if (parts.length > 0 && parts[0]) {\r
299 defaults.channel = '#' + parts[0];\r
300 parts.shift();\r
301 }\r
302 }\r
303\r
304 // If any settings have been given by the server.. override any auto detected settings\r
305 /**\r
306 * Get any server restrictions as set in the server config\r
307 * These settings can not be changed in the server selection dialog\r
308 */\r
309 if (_kiwi.app.server_settings && _kiwi.app.server_settings.connection) {\r
310 if (_kiwi.app.server_settings.connection.server) {\r
311 defaults.server = _kiwi.app.server_settings.connection.server;\r
312 }\r
313\r
314 if (_kiwi.app.server_settings.connection.port) {\r
315 defaults.port = _kiwi.app.server_settings.connection.port;\r
316 }\r
317\r
318 if (_kiwi.app.server_settings.connection.ssl) {\r
319 defaults.ssl = _kiwi.app.server_settings.connection.ssl;\r
320 }\r
321\r
322 if (_kiwi.app.server_settings.connection.channel) {\r
323 defaults.channel = _kiwi.app.server_settings.connection.channel;\r
324 }\r
325\r
326 if (_kiwi.app.server_settings.connection.channel_key) {\r
327 defaults.channel_key = _kiwi.app.server_settings.connection.channel_key;\r
328 }\r
329\r
330 if (_kiwi.app.server_settings.connection.nick) {\r
331 defaults.nick = _kiwi.app.server_settings.connection.nick;\r
332 }\r
333 }\r
334\r
335 // Set any random numbers if needed\r
336 defaults.nick = defaults.nick.replace('?', Math.floor(Math.random() * 100000).toString());\r
337\r
338 if (getQueryVariable('encoding'))\r
339 defaults.encoding = getQueryVariable('encoding');\r
340\r
341 return defaults;\r
342 },\r
b62c8381
D
343};\r
344\r
345\r
346\r
347// If within a closure, expose the kiwi globals\r
348if (typeof global !== 'undefined') {\r
161b5673 349 global.kiwi = _kiwi.global;\r
eaaf73b0 350} else {\r
161b5673
D
351 // Not within a closure so set a var in the current scope\r
352 var kiwi = _kiwi.global;\r
b62c8381 353}