]> jfr.im git - irc/quakenet/qwebirc.git/blob - js/ui/baseui.js
Yet another merge.
[irc/quakenet/qwebirc.git] / js / ui / baseui.js
1 qwebirc.ui.WINDOW_STATUS = 0x01;
2 qwebirc.ui.WINDOW_QUERY = 0x02;
3 qwebirc.ui.WINDOW_CHANNEL = 0x04;
4 qwebirc.ui.WINDOW_CUSTOM = 0x08;
5 qwebirc.ui.WINDOW_CONNECT = 0x10;
6 qwebirc.ui.WINDOW_MESSAGES = 0x20;
7
8 qwebirc.ui.CUSTOM_CLIENT = "custom";
9
10 qwebirc.ui.BaseUI = new Class({
11 Implements: [Events],
12 initialize: function(parentElement, windowClass, uiName, options) {
13 this.options = options;
14
15 this.windows = {};
16 this.clients = {};
17 this.windows[qwebirc.ui.CUSTOM_CLIENT] = {};
18 this.windowArray = [];
19 this.windowClass = windowClass;
20 this.parentElement = parentElement;
21 this.parentElement.addClass("qwebirc");
22 this.parentElement.addClass("qwebirc-" + uiName);
23 this.firstClient = false;
24 this.commandhistory = new qwebirc.irc.CommandHistory();
25 this.clientId = 0;
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));
30 },
31 newClient: function(client) {
32 client.id = this.clientId++;
33 client.hilightController = new qwebirc.ui.HilightController(client);
34
35 this.windows[client.id] = {}
36 this.clients[client.id] = client;
37 var w = this.newWindow(client, qwebirc.ui.WINDOW_STATUS, "Status");
38 this.selectWindow(w);
39 if(!this.firstClient) {
40 this.firstClient = true;
41 w.addLine("", "qwebirc v" + qwebirc.VERSION);
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.");
45 }
46 return w;
47 },
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 },
55 getWindowIdentifier: function(client, type, name) {
56 if(type == qwebirc.ui.WINDOW_MESSAGES)
57 return "-M";
58 if(type == qwebirc.ui.WINDOW_STATUS)
59 return "";
60
61 if(client == qwebirc.ui.CUSTOM_CLIENT) /* HACK */
62 return "_" + name;
63
64 return "_" + client.toIRCLower(name);
65 },
66 newWindow: function(client, type, name) {
67 var w = this.getWindow(client, type, name);
68 if($defined(w))
69 return w;
70
71 var wId = this.getWindowIdentifier(client, type, name);
72 var w = this.windows[this.getClientId(client)][wId] = new this.windowClass(this, client, type, name, wId);
73 this.windowArray.push(w);
74
75 return w;
76 },
77 getWindow: function(client, type, name) {
78 var c = this.windows[this.getClientId(client)];
79 if(!$defined(c))
80 return null;
81
82 return c[this.getWindowIdentifier(client, type, name)];
83 },
84 getActiveWindow: function() {
85 return this.active;
86 },
87 getActiveIRCWindow: function(client) {
88 if(!this.active || this.active.type == qwebirc.ui.WINDOW_CUSTOM) {
89 return this.windows[this.getClientId(client)][this.getWindowIdentifier(client, qwebirc.ui.WINDOW_STATUS)];
90 } else {
91 return this.active;
92 }
93 },
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 */
101 this.updateTitle(window.name + " - " + this.options.appTitle);
102 },
103 updateTitle: function(text) {
104 document.title = text;
105 },
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 },
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);
136 if(index == -1) {
137 return;
138 } else if(index == 0) {
139 this.selectWindow(this.windowArray[1]);
140 } else {
141 this.selectWindow(this.windowArray[index - 1]);
142 }
143 }
144 }
145
146 this.windowArray = this.windowArray.erase(window);
147 delete this.windows[this.getClientId(window.client)][window.identifier];
148 },
149 /*
150 this shouldn't be called by overriding classes!
151 they should implement their own!
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 */
156 loginBox: function(callback, initialNickname, initialChannels, autoConnect, autoNick) {
157 qwebirc.ui.GenericLoginBox(this.parentElement, callback, initialNickname, initialChannels, autoConnect, autoNick, this.options.networkName);
158 },
159 focusChange: function(newValue) {
160 var window_ = this.getActiveWindow();
161 if($defined(window_))
162 window_.focusChange(newValue);
163 }
164 });
165
166 qwebirc.ui.StandardUI = new Class({
167 Extends: qwebirc.ui.BaseUI,
168 UICommands: qwebirc.ui.UI_COMMANDS,
169 initialize: function(parentElement, windowClass, uiName, options) {
170 this.parent(parentElement, windowClass, uiName, options);
171
172 this.tabCompleter = new qwebirc.ui.TabCompleterFactory(this);
173 this.uiOptions = new qwebirc.ui.DefaultOptionsClass(this);
174 this.customWindows = {};
175
176 var ev;
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;
203 }
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
213
214 number = number - 1;
215
216 if(number >= this.windowArray.length)
217 return;
218
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) {
231 if($$("input").indexOf(x.target) == -1 && $$("textarea").indexOf(x.target) == -1)
232 return false;
233 return true;
234 },
235 newCustomWindow: function(name, select, type) {
236 if(!type)
237 type = qwebirc.ui.WINDOW_CUSTOM;
238
239 var w = this.newWindow(qwebirc.ui.CUSTOM_CLIENT, type, name);
240 w.addEvent("close", function(w) {
241 delete this.windows[qwebirc.ui.CUSTOM_CLIENT][w.identifier];
242 }.bind(this));
243
244 if(select)
245 this.selectWindow(w);
246
247 return w;
248 },
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]);
255 return;
256 }
257
258 var d = this.newCustomWindow(windowName, true);
259 this.customWindows[windowName] = d;
260
261 d.addEvent("close", function() {
262 this.customWindows[windowName] = null;
263 }.bind(this));
264
265 if(cssClass)
266 d.lines.addClass("qwebirc-" + cssClass);
267
268 var ew = new class_(d.lines, options);
269 ew.addEvent("close", function() {
270 d.close();
271 }.bind(this));
272
273 d.setSubWindow(ew);
274 },
275 embeddedWindow: function() {
276 this.addCustomWindow("Embedding wizard", qwebirc.ui.EmbedWizard, "embeddedwizard", {baseURL: this.options.baseURL});
277 },
278 optionsWindow: function() {
279 this.addCustomWindow("Options", qwebirc.ui.OptionsPane, "optionspane", this.uiOptions);
280 },
281 aboutWindow: function() {
282 this.addCustomWindow("About", qwebirc.ui.AboutPane, "aboutpane", this.uiOptions);
283 },
284 privacyWindow: function() {
285 this.addCustomWindow("Privacy policy", qwebirc.ui.PrivacyPolicyPane, "privacypolicypane", this.uiOptions);
286 },
287 feedbackWindow: function() {
288 this.addCustomWindow("Feedback", qwebirc.ui.FeedbackPane, "feedbackpane", this.uiOptions);
289 },
290 faqWindow: function() {
291 this.addCustomWindow("FAQ", qwebirc.ui.FAQPane, "faqpane", this.uiOptions);
292 },
293 urlDispatcher: function(name, window) {
294 if(name == "embedded")
295 return ["a", this.embeddedWindow.bind(this)];
296
297 if(name == "options")
298 return ["a", this.optionsWindow.bind(this)];
299
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
307 return null;
308 },
309 tabComplete: function(element) {
310 this.tabCompleter.tabComplete(element);
311 },
312 resetTabComplete: function() {
313 this.tabCompleter.reset();
314 }
315 });
316
317 qwebirc.ui.NotificationUI = new Class({
318 Extends: qwebirc.ui.StandardUI,
319 initialize: function(parentElement, windowClass, uiName, options) {
320 this.parent(parentElement, windowClass, uiName, options);
321
322 this.__beeper = new qwebirc.ui.Beeper(this.uiOptions);
323 this.__flasher = new qwebirc.ui.Flasher(this.uiOptions);
324
325 this.beep = this.__beeper.beep.bind(this.__beeper);
326
327 this.flash = this.__flasher.flash.bind(this.__flasher);
328 this.cancelFlash = this.__flasher.cancelFlash.bind(this.__flasher);
329 },
330 setBeepOnMention: function(value) {
331 if(value)
332 this.__beeper.soundInit();
333 },
334 updateTitle: function(text) {
335 if(this.__flasher.updateTitle(text))
336 this.parent(text);
337 },
338 focusChange: function(value) {
339 this.parent(value);
340 this.__flasher.focusChange(value);
341 }
342 });
343
344 qwebirc.ui.NewLoginUI = new Class({
345 Extends: qwebirc.ui.NotificationUI,
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
359 qwebirc.ui.QuakeNetUI = new Class({
360 Extends: qwebirc.ui.NewLoginUI,
361 urlDispatcher: function(name, window) {
362 if(name == "qwhois") {
363 return ["span", function(auth) {
364 this.client.exec("/MSG Q whois #" + auth);
365 }.bind(window)];
366 }
367 return this.parent(name, window);
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 };
376
377 /* HACK */
378 var foo = function() { document.location = "/auth?logout=1"; };
379 foo.delay(500);
380 }
381 }
382 });
383
384 qwebirc.ui.RootUI = qwebirc.ui.QuakeNetUI;