]> jfr.im git - irc/quakenet/qwebirc.git/blame - js/ui/baseui.js
Add last position indicator (fixes issue 16).
[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;
6qwebirc.ui.WINDOW_MESSAGES = 0x32;
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;
9e769c12
CP
26 },
27 newClient: function(client) {
ffbb638d 28 client.id = this.clientId++;
96f28062
CP
29 client.hilightController = new qwebirc.ui.HilightController(client);
30
ffbb638d
CP
31 this.windows[client.id] = {}
32 this.clients[client.id] = client;
e20e5a6b 33 var w = this.newWindow(client, qwebirc.ui.WINDOW_STATUS, "Status");
9e769c12 34 this.selectWindow(w);
e8db8558
CP
35 if(!this.firstClient) {
36 this.firstClient = true;
e20e5a6b 37 w.addLine("", "qwebirc v" + qwebirc.VERSION);
2dfab0e1
CP
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.");
e8db8558 41 }
9e769c12
CP
42 return w;
43 },
ffbb638d
CP
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 },
fd3734d4 51 getWindowIdentifier: function(client, type, name) {
f74802c5
CP
52 if(type == qwebirc.ui.WINDOW_MESSAGES)
53 return "-M";
e20e5a6b 54 if(type == qwebirc.ui.WINDOW_STATUS)
f74802c5 55 return "";
fd3734d4
CP
56
57 if(client == qwebirc.ui.CUSTOM_CLIENT) /* HACK */
58 return "_" + name;
59
60 return "_" + client.toIRCLower(name);
f74802c5
CP
61 },
62 newWindow: function(client, type, name) {
63 var w = this.getWindow(client, type, name);
64 if($defined(w))
65 return w;
9e769c12 66
fd3734d4 67 var wId = this.getWindowIdentifier(client, type, name);
f74802c5 68 var w = this.windows[this.getClientId(client)][wId] = new this.windowClass(this, client, type, name, wId);
9e769c12
CP
69 this.windowArray.push(w);
70
71 return w;
72 },
f74802c5
CP
73 getWindow: function(client, type, name) {
74 var c = this.windows[this.getClientId(client)];
75 if(!$defined(c))
76 return null;
77
fd3734d4 78 return c[this.getWindowIdentifier(client, type, name)];
f74802c5 79 },
9e769c12
CP
80 getActiveWindow: function() {
81 return this.active;
82 },
1d42a76f
CP
83 getActiveIRCWindow: function(client) {
84 if(!this.active || this.active.type == qwebirc.ui.WINDOW_CUSTOM) {
fd3734d4 85 return this.windows[this.getClientId(client)][this.getWindowIdentifier(client, qwebirc.ui.WINDOW_STATUS)];
1d42a76f
CP
86 } else {
87 return this.active;
88 }
89 },
9e769c12
CP
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 */
326478c2
CP
97 this.updateTitle(window.name + " - " + this.options.appTitle);
98 },
99 updateTitle: function(text) {
100 document.title = text;
9e769c12 101 },
ff4befd8
CP
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 },
9e769c12
CP
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);
6f2e4a37
CP
132 if(index == -1) {
133 return;
134 } else if(index == 0) {
9e769c12
CP
135 this.selectWindow(this.windowArray[1]);
136 } else {
137 this.selectWindow(this.windowArray[index - 1]);
138 }
9e769c12
CP
139 }
140 }
141
404cfb58 142 this.windowArray = this.windowArray.erase(window);
ffbb638d 143 delete this.windows[this.getClientId(window.client)][window.identifier];
eb9b087b 144 },
eb9b087b
CP
145 /*
146 this shouldn't be called by overriding classes!
66de775f 147 they should implement their own!
eb9b087b
CP
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 */
66de775f 152 loginBox: function(callback, initialNickname, initialChannels, autoConnect, autoNick) {
2cad083e 153 qwebirc.ui.GenericLoginBox(this.parentElement, callback, initialNickname, initialChannels, autoConnect, autoNick, this.options.networkName);
9e769c12
CP
154 }
155});
381fddfd 156
e20e5a6b
CP
157qwebirc.ui.StandardUI = new Class({
158 Extends: qwebirc.ui.BaseUI,
f3d0c9f5 159 UICommands: qwebirc.ui.UI_COMMANDS,
381fddfd
CP
160 initialize: function(parentElement, windowClass, uiName, options) {
161 this.parent(parentElement, windowClass, uiName, options);
3184781b
CP
162
163 this.tabCompleter = new qwebirc.ui.TabCompleterFactory(this);
fb71087a 164 this.uiOptions = new qwebirc.ui.DefaultOptionsClass(this);
ebb21d2e
CP
165 this.customWindows = {};
166
2a802692 167 var ev;
20157c51
CP
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;
381fddfd 194 }
20157c51
CP
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
424608ac 204
20157c51
CP
205 number = number - 1;
206
207 if(number >= this.windowArray.length)
208 return;
381fddfd 209
20157c51
CP
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) {
deebe19a
CP
222 if($$("input").indexOf(x.target) == -1 && $$("textarea").indexOf(x.target) == -1)
223 return false;
224 return true;
841a451d 225 },
8af49135
CP
226 newCustomWindow: function(name, select, type) {
227 if(!type)
e20e5a6b 228 type = qwebirc.ui.WINDOW_CUSTOM;
8af49135 229
e20e5a6b 230 var w = this.newWindow(qwebirc.ui.CUSTOM_CLIENT, type, name);
8af49135 231 w.addEvent("close", function(w) {
f74802c5 232 delete this.windows[qwebirc.ui.CUSTOM_CLIENT][w.identifier];
8af49135
CP
233 }.bind(this));
234
235 if(select)
236 this.selectWindow(w);
6c19eb8f 237
8af49135
CP
238 return w;
239 },
ebb21d2e
CP
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]);
8af49135 246 return;
841a451d 247 }
8af49135 248
ebb21d2e
CP
249 var d = this.newCustomWindow(windowName, true);
250 this.customWindows[windowName] = d;
251
252 d.addEvent("close", function() {
253 this.customWindows[windowName] = null;
8af49135
CP
254 }.bind(this));
255
ebb21d2e 256 if(cssClass)
e1a91a8a 257 d.lines.addClass("qwebirc-" + cssClass);
ebb21d2e
CP
258
259 var ew = new class_(d.lines, options);
8af49135 260 ew.addEvent("close", function() {
ebb21d2e 261 d.close();
8af49135 262 }.bind(this));
17f40fd9
CP
263
264 d.setSubWindow(ew);
841a451d 265 },
ebb21d2e 266 embeddedWindow: function() {
2dfab0e1 267 this.addCustomWindow("Embedding wizard", qwebirc.ui.EmbedWizard, "embeddedwizard", {baseURL: this.options.baseURL});
ebb21d2e
CP
268 },
269 optionsWindow: function() {
270 this.addCustomWindow("Options", qwebirc.ui.OptionsPane, "optionspane", this.uiOptions);
271 },
e1a91a8a
CP
272 aboutWindow: function() {
273 this.addCustomWindow("About", qwebirc.ui.AboutPane, "aboutpane", this.uiOptions);
274 },
b35116e2
CP
275 privacyWindow: function() {
276 this.addCustomWindow("Privacy policy", qwebirc.ui.PrivacyPolicyPane, "privacypolicypane", this.uiOptions);
277 },
391f51ff
CP
278 feedbackWindow: function() {
279 this.addCustomWindow("Feedback", qwebirc.ui.FeedbackPane, "feedbackpane", this.uiOptions);
280 },
f3d0c9f5
CP
281 faqWindow: function() {
282 this.addCustomWindow("FAQ", qwebirc.ui.FAQPane, "faqpane", this.uiOptions);
283 },
144ee52f 284 urlDispatcher: function(name, window) {
8af49135 285 if(name == "embedded")
925fc357 286 return ["a", this.embeddedWindow.bind(this)];
ebb21d2e
CP
287
288 if(name == "options")
289 return ["a", this.optionsWindow.bind(this)];
8af49135 290
5f2808af
CP
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
8af49135 298 return null;
3184781b
CP
299 },
300 tabComplete: function(element) {
301 this.tabCompleter.tabComplete(element);
302 },
303 resetTabComplete: function() {
304 this.tabCompleter.reset();
8af49135 305 }
381fddfd 306});
6f2e4a37 307
326478c2 308qwebirc.ui.NotificationUI = new Class({
e20e5a6b 309 Extends: qwebirc.ui.StandardUI,
fb71087a
CP
310 initialize: function(parentElement, windowClass, uiName, options) {
311 this.parent(parentElement, windowClass, uiName, options);
312
326478c2
CP
313 this.__beeper = new qwebirc.ui.Beeper(this.uiOptions);
314 this.__flasher = new qwebirc.ui.Flasher(this.uiOptions);
fb71087a 315
326478c2 316 this.beep = this.__beeper.beep.bind(this.__beeper);
127631e0 317
326478c2
CP
318 this.flash = this.__flasher.flash.bind(this.__flasher);
319 this.cancelFlash = this.__flasher.cancelFlash.bind(this.__flasher);
fb71087a 320 },
127631e0
CP
321 setBeepOnMention: function(value) {
322 if(value)
326478c2
CP
323 this.__beeper.soundInit();
324 },
325 updateTitle: function(text) {
326 if(this.__flasher.updateTitle(text))
327 this.parent(text);
1211ddcd 328 }
fb71087a
CP
329});
330
5f2808af 331qwebirc.ui.NewLoginUI = new Class({
326478c2 332 Extends: qwebirc.ui.NotificationUI,
5f2808af
CP
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
346qwebirc.ui.QuakeNetUI = new Class({
347 Extends: qwebirc.ui.NewLoginUI,
2cd9e32d
CP
348 urlDispatcher: function(name, window) {
349 if(name == "qwhois") {
7cb09779 350 return ["span", function(auth) {
2cd9e32d 351 this.client.exec("/MSG Q whois #" + auth);
925fc357
CP
352 }.bind(window)];
353 }
144ee52f 354 return this.parent(name, window);
ffbb638d
CP
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 };
4b9f894d
CP
363
364 /* HACK */
365 var foo = function() { document.location = "/auth?logout=1"; };
366 foo.delay(500);
ffbb638d 367 }
2cd9e32d
CP
368 }
369});
144ee52f
CP
370
371qwebirc.ui.RootUI = qwebirc.ui.QuakeNetUI;