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