]> jfr.im git - irc/quakenet/qwebirc.git/blame - js/ui/baseui.js
Add nick colouring (resolves issue 44).
[irc/quakenet/qwebirc.git] / js / ui / baseui.js
CommitLineData
3e66d49c
CP
1qwebirc.ui.WINDOW_STATUS = 0x01;
2qwebirc.ui.WINDOW_QUERY = 0x02;
3qwebirc.ui.WINDOW_CHANNEL = 0x04;
4qwebirc.ui.WINDOW_CUSTOM = 0x08;
5qwebirc.ui.WINDOW_CONNECT = 0x10;
8c3e644b 6qwebirc.ui.WINDOW_MESSAGES = 0x20;
3e66d49c 7
e20e5a6b 8qwebirc.ui.CUSTOM_CLIENT = "custom";
9e769c12 9
e20e5a6b 10qwebirc.ui.BaseUI = new Class({
2cad083e 11 Implements: [Events],
a59dc700 12 initialize: function(parentElement, windowClass, uiName, options) {
2cad083e 13 this.options = options;
a59dc700 14
9e769c12 15 this.windows = {};
ffbb638d 16 this.clients = {};
e20e5a6b 17 this.windows[qwebirc.ui.CUSTOM_CLIENT] = {};
9e769c12
CP
18 this.windowArray = [];
19 this.windowClass = windowClass;
20 this.parentElement = parentElement;
21 this.parentElement.addClass("qwebirc");
22 this.parentElement.addClass("qwebirc-" + uiName);
e8db8558 23 this.firstClient = false;
e20e5a6b 24 this.commandhistory = new qwebirc.irc.CommandHistory();
ffbb638d 25 this.clientId = 0;
eb271d86
CP
26
27 this.windowFocused = true;
28 window.addEvent("blur", function() { if(this.windowFocused) { this.windowFocused = false; this.focusChange(false); } }.bind(this));
29 window.addEvent("focus", function() { if(!this.windowFocused) { this.windowFocused = true; this.focusChange(true); } }.bind(this));
9e769c12
CP
30 },
31 newClient: function(client) {
ffbb638d 32 client.id = this.clientId++;
96f28062
CP
33 client.hilightController = new qwebirc.ui.HilightController(client);
34
ffbb638d
CP
35 this.windows[client.id] = {}
36 this.clients[client.id] = client;
e20e5a6b 37 var w = this.newWindow(client, qwebirc.ui.WINDOW_STATUS, "Status");
9e769c12 38 this.selectWindow(w);
e8db8558
CP
39 if(!this.firstClient) {
40 this.firstClient = true;
e20e5a6b 41 w.addLine("", "qwebirc v" + qwebirc.VERSION);
2dfab0e1
CP
42 w.addLine("", "Copyright (C) 2008-2009 Chris Porter and the qwebirc project.");
43 w.addLine("", "http://www.qwebirc.org");
44 w.addLine("", "Licensed under the GNU General Public License, Version 2.");
e8db8558 45 }
9e769c12
CP
46 return w;
47 },
ffbb638d
CP
48 getClientId: function(client) {
49 if(client == qwebirc.ui.CUSTOM_CLIENT) {
50 return qwebirc.ui.CUSTOM_CLIENT;
51 } else {
52 return client.id;
53 }
54 },
fd3734d4 55 getWindowIdentifier: function(client, type, name) {
f74802c5
CP
56 if(type == qwebirc.ui.WINDOW_MESSAGES)
57 return "-M";
e20e5a6b 58 if(type == qwebirc.ui.WINDOW_STATUS)
f74802c5 59 return "";
fd3734d4
CP
60
61 if(client == qwebirc.ui.CUSTOM_CLIENT) /* HACK */
62 return "_" + name;
63
64 return "_" + client.toIRCLower(name);
f74802c5
CP
65 },
66 newWindow: function(client, type, name) {
67 var w = this.getWindow(client, type, name);
68 if($defined(w))
69 return w;
9e769c12 70
fd3734d4 71 var wId = this.getWindowIdentifier(client, type, name);
f74802c5 72 var w = this.windows[this.getClientId(client)][wId] = new this.windowClass(this, client, type, name, wId);
9e769c12
CP
73 this.windowArray.push(w);
74
75 return w;
76 },
f74802c5
CP
77 getWindow: function(client, type, name) {
78 var c = this.windows[this.getClientId(client)];
79 if(!$defined(c))
80 return null;
81
fd3734d4 82 return c[this.getWindowIdentifier(client, type, name)];
f74802c5 83 },
9e769c12
CP
84 getActiveWindow: function() {
85 return this.active;
86 },
1d42a76f
CP
87 getActiveIRCWindow: function(client) {
88 if(!this.active || this.active.type == qwebirc.ui.WINDOW_CUSTOM) {
fd3734d4 89 return this.windows[this.getClientId(client)][this.getWindowIdentifier(client, qwebirc.ui.WINDOW_STATUS)];
1d42a76f
CP
90 } else {
91 return this.active;
92 }
93 },
9e769c12
CP
94 __setActiveWindow: function(window) {
95 this.active = window;
96 },
97 selectWindow: function(window) {
98 if(this.active)
99 this.active.deselect();
100 window.select(); /* calls setActiveWindow */
326478c2
CP
101 this.updateTitle(window.name + " - " + this.options.appTitle);
102 },
103 updateTitle: function(text) {
104 document.title = text;
9e769c12 105 },
ff4befd8
CP
106 nextWindow: function(direction) {
107 if(this.windowArray.length == 0 || !this.active)
108 return;
109
110 if(!direction)
111 direction = 1;
112
113 var index = this.windowArray.indexOf(this.active);
114 if(index == -1)
115 return;
116
117 index = index + direction;
118 if(index < 0) {
119 index = this.windowArray.length - 1;
120 } else if(index >= this.windowArray.length) {
121 index = 0;
122 }
123
124 this.selectWindow(this.windowArray[index]);
125 },
126 prevWindow: function() {
127 this.nextWindow(-1);
128 },
9e769c12
CP
129 __closed: function(window) {
130 if(window.active) {
131 this.active = undefined;
132 if(this.windowArray.length == 1) {
133 this.windowArray = [];
134 } else {
135 var index = this.windowArray.indexOf(window);
6f2e4a37
CP
136 if(index == -1) {
137 return;
138 } else if(index == 0) {
9e769c12
CP
139 this.selectWindow(this.windowArray[1]);
140 } else {
141 this.selectWindow(this.windowArray[index - 1]);
142 }
9e769c12
CP
143 }
144 }
145
404cfb58 146 this.windowArray = this.windowArray.erase(window);
ffbb638d 147 delete this.windows[this.getClientId(window.client)][window.identifier];
eb9b087b 148 },
eb9b087b
CP
149 /*
150 this shouldn't be called by overriding classes!
66de775f 151 they should implement their own!
eb9b087b
CP
152 some form of user input MUST be received before an
153 IRC connection is made, else users are going to get
154 tricked into getting themselves glined
155 */
66de775f 156 loginBox: function(callback, initialNickname, initialChannels, autoConnect, autoNick) {
2cad083e 157 qwebirc.ui.GenericLoginBox(this.parentElement, callback, initialNickname, initialChannels, autoConnect, autoNick, this.options.networkName);
eb271d86
CP
158 },
159 focusChange: function(newValue) {
160 var window_ = this.getActiveWindow();
161 if($defined(window_))
162 window_.focusChange(newValue);
9e769c12
CP
163 }
164});
381fddfd 165
e20e5a6b
CP
166qwebirc.ui.StandardUI = new Class({
167 Extends: qwebirc.ui.BaseUI,
f3d0c9f5 168 UICommands: qwebirc.ui.UI_COMMANDS,
381fddfd
CP
169 initialize: function(parentElement, windowClass, uiName, options) {
170 this.parent(parentElement, windowClass, uiName, options);
3184781b
CP
171
172 this.tabCompleter = new qwebirc.ui.TabCompleterFactory(this);
fb71087a 173 this.uiOptions = new qwebirc.ui.DefaultOptionsClass(this);
ebb21d2e
CP
174 this.customWindows = {};
175
2a802692 176 var ev;
20157c51
CP
177 if(Browser.Engine.trident) {
178 ev = "keydown";
179 } else {
180 ev = "keypress";
181 }
182 document.addEvent(ev, this.__handleHotkey.bind(this));
183 },
184 __handleHotkey: function(x) {
185 if(!x.alt || x.control) {
186 if(x.key == "backspace" || x.key == "/")
187 if(!this.getInputFocused(x))
188 new Event(x).stop();
189 return;
190 }
191 var success = false;
192 if(x.key == "a" || x.key == "A") {
193 var highestNum = 0;
194 var highestIndex = -1;
195 success = true;
196
197 new Event(x).stop();
198 for(var i=0;i<this.windowArray.length;i++) {
199 var h = this.windowArray[i].hilighted;
200 if(h > highestNum) {
201 highestIndex = i;
202 highestNum = h;
381fddfd 203 }
20157c51
CP
204 }
205 if(highestIndex > -1)
206 this.selectWindow(this.windowArray[highestIndex]);
207 } else if(x.key >= '0' && x.key <= '9') {
208 success = true;
209
210 number = x.key - '0';
211 if(number == 0)
212 number = 10
424608ac 213
20157c51
CP
214 number = number - 1;
215
216 if(number >= this.windowArray.length)
217 return;
381fddfd 218
20157c51
CP
219 this.selectWindow(this.windowArray[number]);
220 } else if(x.key == "left") {
221 this.prevWindow();
222 success = true;
223 } else if(x.key == "right") {
224 this.nextWindow();
225 success = true;
226 }
227 if(success)
228 new Event(x).stop();
229 },
230 getInputFocused: function(x) {
deebe19a
CP
231 if($$("input").indexOf(x.target) == -1 && $$("textarea").indexOf(x.target) == -1)
232 return false;
233 return true;
841a451d 234 },
8af49135
CP
235 newCustomWindow: function(name, select, type) {
236 if(!type)
e20e5a6b 237 type = qwebirc.ui.WINDOW_CUSTOM;
8af49135 238
e20e5a6b 239 var w = this.newWindow(qwebirc.ui.CUSTOM_CLIENT, type, name);
8af49135 240 w.addEvent("close", function(w) {
f74802c5 241 delete this.windows[qwebirc.ui.CUSTOM_CLIENT][w.identifier];
8af49135
CP
242 }.bind(this));
243
244 if(select)
245 this.selectWindow(w);
6c19eb8f 246
8af49135
CP
247 return w;
248 },
ebb21d2e
CP
249 addCustomWindow: function(windowName, class_, cssClass, options) {
250 if(!$defined(options))
251 options = {};
252
253 if(this.customWindows[windowName]) {
254 this.selectWindow(this.customWindows[windowName]);
8af49135 255 return;
841a451d 256 }
8af49135 257
ebb21d2e
CP
258 var d = this.newCustomWindow(windowName, true);
259 this.customWindows[windowName] = d;
260
261 d.addEvent("close", function() {
262 this.customWindows[windowName] = null;
8af49135
CP
263 }.bind(this));
264
ebb21d2e 265 if(cssClass)
e1a91a8a 266 d.lines.addClass("qwebirc-" + cssClass);
ebb21d2e
CP
267
268 var ew = new class_(d.lines, options);
8af49135 269 ew.addEvent("close", function() {
ebb21d2e 270 d.close();
8af49135 271 }.bind(this));
17f40fd9
CP
272
273 d.setSubWindow(ew);
841a451d 274 },
ebb21d2e 275 embeddedWindow: function() {
2dfab0e1 276 this.addCustomWindow("Embedding wizard", qwebirc.ui.EmbedWizard, "embeddedwizard", {baseURL: this.options.baseURL});
ebb21d2e
CP
277 },
278 optionsWindow: function() {
279 this.addCustomWindow("Options", qwebirc.ui.OptionsPane, "optionspane", this.uiOptions);
280 },
e1a91a8a
CP
281 aboutWindow: function() {
282 this.addCustomWindow("About", qwebirc.ui.AboutPane, "aboutpane", this.uiOptions);
283 },
b35116e2
CP
284 privacyWindow: function() {
285 this.addCustomWindow("Privacy policy", qwebirc.ui.PrivacyPolicyPane, "privacypolicypane", this.uiOptions);
286 },
391f51ff
CP
287 feedbackWindow: function() {
288 this.addCustomWindow("Feedback", qwebirc.ui.FeedbackPane, "feedbackpane", this.uiOptions);
289 },
f3d0c9f5
CP
290 faqWindow: function() {
291 this.addCustomWindow("FAQ", qwebirc.ui.FAQPane, "faqpane", this.uiOptions);
292 },
144ee52f 293 urlDispatcher: function(name, window) {
8af49135 294 if(name == "embedded")
925fc357 295 return ["a", this.embeddedWindow.bind(this)];
ebb21d2e
CP
296
297 if(name == "options")
298 return ["a", this.optionsWindow.bind(this)];
8af49135 299
5f2808af
CP
300 /* doesn't really belong here */
301 if(name == "whois") {
302 return ["span", function(nick) {
303 this.client.exec("/WHOIS " + nick);
304 }.bind(window)];
305 }
306
8af49135 307 return null;
3184781b
CP
308 },
309 tabComplete: function(element) {
310 this.tabCompleter.tabComplete(element);
311 },
312 resetTabComplete: function() {
313 this.tabCompleter.reset();
8af49135 314 }
381fddfd 315});
6f2e4a37 316
326478c2 317qwebirc.ui.NotificationUI = new Class({
e20e5a6b 318 Extends: qwebirc.ui.StandardUI,
fb71087a
CP
319 initialize: function(parentElement, windowClass, uiName, options) {
320 this.parent(parentElement, windowClass, uiName, options);
321
326478c2
CP
322 this.__beeper = new qwebirc.ui.Beeper(this.uiOptions);
323 this.__flasher = new qwebirc.ui.Flasher(this.uiOptions);
fb71087a 324
326478c2 325 this.beep = this.__beeper.beep.bind(this.__beeper);
127631e0 326
326478c2
CP
327 this.flash = this.__flasher.flash.bind(this.__flasher);
328 this.cancelFlash = this.__flasher.cancelFlash.bind(this.__flasher);
fb71087a 329 },
127631e0
CP
330 setBeepOnMention: function(value) {
331 if(value)
326478c2
CP
332 this.__beeper.soundInit();
333 },
334 updateTitle: function(text) {
335 if(this.__flasher.updateTitle(text))
336 this.parent(text);
eb271d86
CP
337 },
338 focusChange: function(value) {
339 this.parent(value);
340 this.__flasher.focusChange(value);
1211ddcd 341 }
fb71087a
CP
342});
343
5f2808af 344qwebirc.ui.NewLoginUI = new Class({
326478c2 345 Extends: qwebirc.ui.NotificationUI,
5f2808af
CP
346 loginBox: function(callbackfn, initialNickname, initialChannels, autoConnect, autoNick) {
347 this.postInitialize();
348
349 var w = this.newCustomWindow("Connect", true, qwebirc.ui.WINDOW_CONNECT);
350 var callback = function(args) {
351 w.close();
352 callbackfn(args);
353 };
354
355 qwebirc.ui.GenericLoginBox(w.lines, callback, initialNickname, initialChannels, autoConnect, autoNick, this.options.networkName);
356 }
357});
358
359qwebirc.ui.QuakeNetUI = new Class({
360 Extends: qwebirc.ui.NewLoginUI,
2cd9e32d
CP
361 urlDispatcher: function(name, window) {
362 if(name == "qwhois") {
7cb09779 363 return ["span", function(auth) {
2cd9e32d 364 this.client.exec("/MSG Q whois #" + auth);
925fc357
CP
365 }.bind(window)];
366 }
144ee52f 367 return this.parent(name, window);
ffbb638d
CP
368 },
369 logout: function() {
370 if(!qwebirc.auth.loggedin())
371 return;
372 if(confirm("Log out?")) {
373 for(var client in this.clients) {
374 this.clients[client].quit("Logged out");
375 };
4b9f894d
CP
376
377 /* HACK */
378 var foo = function() { document.location = "/auth?logout=1"; };
379 foo.delay(500);
ffbb638d 380 }
2cd9e32d
CP
381 }
382});
144ee52f
CP
383
384qwebirc.ui.RootUI = qwebirc.ui.QuakeNetUI;