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