]> jfr.im git - irc/quakenet/qwebirc.git/blame - js/ui/baseui.js
Add WEBIRC support, along with hex idents.
[irc/quakenet/qwebirc.git] / js / ui / baseui.js
CommitLineData
e20e5a6b
CP
1qwebirc.ui.WINDOW_STATUS = 1;
2qwebirc.ui.WINDOW_QUERY = 2;
3qwebirc.ui.WINDOW_CHANNEL = 3;
4qwebirc.ui.WINDOW_CUSTOM = 4;
5qwebirc.ui.WINDOW_CONNECT = 5;
f74802c5 6qwebirc.ui.WINDOW_MESSAGES = 6;
e20e5a6b 7qwebirc.ui.CUSTOM_CLIENT = "custom";
9e769c12 8
e20e5a6b 9qwebirc.ui.BaseUI = new Class({
2cad083e 10 Implements: [Events],
a59dc700 11 initialize: function(parentElement, windowClass, uiName, options) {
2cad083e 12 this.options = options;
a59dc700 13
9e769c12 14 this.windows = {};
ffbb638d 15 this.clients = {};
e20e5a6b 16 this.windows[qwebirc.ui.CUSTOM_CLIENT] = {};
9e769c12
CP
17 this.windowArray = [];
18 this.windowClass = windowClass;
19 this.parentElement = parentElement;
20 this.parentElement.addClass("qwebirc");
21 this.parentElement.addClass("qwebirc-" + uiName);
e8db8558 22 this.firstClient = false;
e20e5a6b 23 this.commandhistory = new qwebirc.irc.CommandHistory();
ffbb638d 24 this.clientId = 0;
9e769c12
CP
25 },
26 newClient: function(client) {
ffbb638d 27 client.id = this.clientId++;
96f28062
CP
28 client.hilightController = new qwebirc.ui.HilightController(client);
29
ffbb638d
CP
30 this.windows[client.id] = {}
31 this.clients[client.id] = client;
e20e5a6b 32 var w = this.newWindow(client, qwebirc.ui.WINDOW_STATUS, "Status");
9e769c12 33 this.selectWindow(w);
e8db8558
CP
34 if(!this.firstClient) {
35 this.firstClient = true;
e20e5a6b 36 w.addLine("", "qwebirc v" + qwebirc.VERSION);
391f51ff 37 w.addLine("", "Copyright (C) 2008-2009 Chris Porter. All rights reserved.");
e8db8558 38 w.addLine("", "http://webchat.quakenet.org/");
4094890f 39 w.addLine("", "This is BETA quality software, please report bugs to slug@quakenet.org");
e8db8558 40 }
9e769c12
CP
41 return w;
42 },
ffbb638d
CP
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 },
f74802c5
CP
50 getWindowIdentifier: function(type, name) {
51 if(type == qwebirc.ui.WINDOW_MESSAGES)
52 return "-M";
e20e5a6b 53 if(type == qwebirc.ui.WINDOW_STATUS)
f74802c5 54 return "";
26c81b65 55 return "_" + name.toIRCLower();
f74802c5
CP
56 },
57 newWindow: function(client, type, name) {
58 var w = this.getWindow(client, type, name);
59 if($defined(w))
60 return w;
9e769c12 61
f74802c5
CP
62 var wId = this.getWindowIdentifier(type, name);
63 var w = this.windows[this.getClientId(client)][wId] = new this.windowClass(this, client, type, name, wId);
9e769c12
CP
64 this.windowArray.push(w);
65
66 return w;
67 },
f74802c5
CP
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 },
9e769c12
CP
75 getActiveWindow: function() {
76 return this.active;
77 },
1d42a76f
CP
78 getActiveIRCWindow: function(client) {
79 if(!this.active || this.active.type == qwebirc.ui.WINDOW_CUSTOM) {
f74802c5 80 return this.windows[this.getClientId(client)][this.getWindowIdentifier(qwebirc.ui.WINDOW_STATUS)];
1d42a76f
CP
81 } else {
82 return this.active;
83 }
84 },
9e769c12
CP
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 */
a59dc700 92 document.title = window.name + " - " + this.options.appTitle;
9e769c12 93 },
ff4befd8
CP
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 },
9e769c12
CP
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);
6f2e4a37
CP
124 if(index == -1) {
125 return;
126 } else if(index == 0) {
9e769c12
CP
127 this.selectWindow(this.windowArray[1]);
128 } else {
129 this.selectWindow(this.windowArray[index - 1]);
130 }
9e769c12
CP
131 }
132 }
133
404cfb58 134 this.windowArray = this.windowArray.erase(window);
ffbb638d 135 delete this.windows[this.getClientId(window.client)][window.identifier];
eb9b087b 136 },
eb9b087b
CP
137 /*
138 this shouldn't be called by overriding classes!
66de775f 139 they should implement their own!
eb9b087b
CP
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 */
66de775f 144 loginBox: function(callback, initialNickname, initialChannels, autoConnect, autoNick) {
2cad083e 145 qwebirc.ui.GenericLoginBox(this.parentElement, callback, initialNickname, initialChannels, autoConnect, autoNick, this.options.networkName);
9e769c12
CP
146 }
147});
381fddfd 148
e20e5a6b
CP
149qwebirc.ui.StandardUI = new Class({
150 Extends: qwebirc.ui.BaseUI,
f3d0c9f5 151 UICommands: qwebirc.ui.UI_COMMANDS,
381fddfd
CP
152 initialize: function(parentElement, windowClass, uiName, options) {
153 this.parent(parentElement, windowClass, uiName, options);
3184781b
CP
154
155 this.tabCompleter = new qwebirc.ui.TabCompleterFactory(this);
fb71087a 156 this.uiOptions = new qwebirc.ui.DefaultOptionsClass(this);
ebb21d2e
CP
157 this.customWindows = {};
158
2a802692 159 var ev;
20157c51
CP
160 if(Browser.Engine.trident) {
161 ev = "keydown";
162 } else {
163 ev = "keypress";
164 }
165 document.addEvent(ev, this.__handleHotkey.bind(this));
166 },
167 __handleHotkey: function(x) {
168 if(!x.alt || x.control) {
169 if(x.key == "backspace" || x.key == "/")
170 if(!this.getInputFocused(x))
171 new Event(x).stop();
172 return;
173 }
174 var success = false;
175 if(x.key == "a" || x.key == "A") {
176 var highestNum = 0;
177 var highestIndex = -1;
178 success = true;
179
180 new Event(x).stop();
181 for(var i=0;i<this.windowArray.length;i++) {
182 var h = this.windowArray[i].hilighted;
183 if(h > highestNum) {
184 highestIndex = i;
185 highestNum = h;
381fddfd 186 }
20157c51
CP
187 }
188 if(highestIndex > -1)
189 this.selectWindow(this.windowArray[highestIndex]);
190 } else if(x.key >= '0' && x.key <= '9') {
191 success = true;
192
193 number = x.key - '0';
194 if(number == 0)
195 number = 10
424608ac 196
20157c51
CP
197 number = number - 1;
198
199 if(number >= this.windowArray.length)
200 return;
381fddfd 201
20157c51
CP
202 this.selectWindow(this.windowArray[number]);
203 } else if(x.key == "left") {
204 this.prevWindow();
205 success = true;
206 } else if(x.key == "right") {
207 this.nextWindow();
208 success = true;
209 }
210 if(success)
211 new Event(x).stop();
212 },
213 getInputFocused: function(x) {
deebe19a
CP
214 if($$("input").indexOf(x.target) == -1 && $$("textarea").indexOf(x.target) == -1)
215 return false;
216 return true;
841a451d 217 },
8af49135
CP
218 newCustomWindow: function(name, select, type) {
219 if(!type)
e20e5a6b 220 type = qwebirc.ui.WINDOW_CUSTOM;
8af49135 221
e20e5a6b 222 var w = this.newWindow(qwebirc.ui.CUSTOM_CLIENT, type, name);
8af49135 223 w.addEvent("close", function(w) {
f74802c5 224 delete this.windows[qwebirc.ui.CUSTOM_CLIENT][w.identifier];
8af49135
CP
225 }.bind(this));
226
227 if(select)
228 this.selectWindow(w);
6c19eb8f 229
8af49135
CP
230 return w;
231 },
ebb21d2e
CP
232 addCustomWindow: function(windowName, class_, cssClass, options) {
233 if(!$defined(options))
234 options = {};
235
236 if(this.customWindows[windowName]) {
237 this.selectWindow(this.customWindows[windowName]);
8af49135 238 return;
841a451d 239 }
8af49135 240
ebb21d2e
CP
241 var d = this.newCustomWindow(windowName, true);
242 this.customWindows[windowName] = d;
243
244 d.addEvent("close", function() {
245 this.customWindows[windowName] = null;
8af49135
CP
246 }.bind(this));
247
ebb21d2e 248 if(cssClass)
e1a91a8a 249 d.lines.addClass("qwebirc-" + cssClass);
ebb21d2e
CP
250
251 var ew = new class_(d.lines, options);
8af49135 252 ew.addEvent("close", function() {
ebb21d2e 253 d.close();
8af49135 254 }.bind(this));
17f40fd9
CP
255
256 d.setSubWindow(ew);
841a451d 257 },
ebb21d2e 258 embeddedWindow: function() {
b35116e2 259 this.addCustomWindow("Embedding wizard", qwebirc.ui.EmbedWizard, "embeddedwizard");
ebb21d2e
CP
260 },
261 optionsWindow: function() {
262 this.addCustomWindow("Options", qwebirc.ui.OptionsPane, "optionspane", this.uiOptions);
263 },
e1a91a8a
CP
264 aboutWindow: function() {
265 this.addCustomWindow("About", qwebirc.ui.AboutPane, "aboutpane", this.uiOptions);
266 },
b35116e2
CP
267 privacyWindow: function() {
268 this.addCustomWindow("Privacy policy", qwebirc.ui.PrivacyPolicyPane, "privacypolicypane", this.uiOptions);
269 },
391f51ff
CP
270 feedbackWindow: function() {
271 this.addCustomWindow("Feedback", qwebirc.ui.FeedbackPane, "feedbackpane", this.uiOptions);
272 },
f3d0c9f5
CP
273 faqWindow: function() {
274 this.addCustomWindow("FAQ", qwebirc.ui.FAQPane, "faqpane", this.uiOptions);
275 },
8af49135
CP
276 urlDispatcher: function(name) {
277 if(name == "embedded")
925fc357 278 return ["a", this.embeddedWindow.bind(this)];
ebb21d2e
CP
279
280 if(name == "options")
281 return ["a", this.optionsWindow.bind(this)];
8af49135
CP
282
283 return null;
3184781b
CP
284 },
285 tabComplete: function(element) {
286 this.tabCompleter.tabComplete(element);
287 },
288 resetTabComplete: function() {
289 this.tabCompleter.reset();
8af49135 290 }
381fddfd 291});
6f2e4a37 292
fb71087a 293qwebirc.ui.SoundUI = new Class({
e20e5a6b 294 Extends: qwebirc.ui.StandardUI,
fb71087a
CP
295 initialize: function(parentElement, windowClass, uiName, options) {
296 this.parent(parentElement, windowClass, uiName, options);
297
127631e0 298 this.soundInited = false;
fb71087a 299 this.soundReady = false;
fb71087a 300
127631e0 301 this.setBeepOnMention(this.uiOptions.BEEP_ON_MENTION);
fb71087a 302 },
127631e0
CP
303 soundInit: function() {
304 if(this.soundInited)
fb71087a 305 return;
127631e0
CP
306 if(!$defined(Browser.Plugins.Flash) || Browser.Plugins.Flash.version < 8)
307 return;
308 this.soundInited = true;
309
310 this.soundPlayer = new qwebirc.sound.SoundPlayer();
311 this.soundPlayer.addEvent("ready", function() {
312 this.soundReady = true;
313 }.bind(this));
314 this.soundPlayer.go();
fb71087a 315 },
127631e0
CP
316 setBeepOnMention: function(value) {
317 if(value)
318 this.soundInit();
319 this.beepOnMention = value;
320 },
321 beep: function() {
322 if(!this.soundReady || !this.beepOnMention)
fb71087a 323 return;
127631e0
CP
324
325 this.soundPlayer.beep();
fb71087a
CP
326 }
327});
328
329qwebirc.ui.QuakeNetUI = new Class({
330 Extends: qwebirc.ui.SoundUI,
2cd9e32d
CP
331 urlDispatcher: function(name, window) {
332 if(name == "qwhois") {
7cb09779 333 return ["span", function(auth) {
2cd9e32d 334 this.client.exec("/MSG Q whois #" + auth);
925fc357
CP
335 }.bind(window)];
336 }
337 if(name == "whois") {
338 return ["span", function(nick) {
339 this.client.exec("/WHOIS " + nick);
340 }.bind(window)];
2cd9e32d 341 }
2cd9e32d 342 return this.parent(name);
ffbb638d
CP
343 },
344 logout: function() {
345 if(!qwebirc.auth.loggedin())
346 return;
347 if(confirm("Log out?")) {
348 for(var client in this.clients) {
349 this.clients[client].quit("Logged out");
350 };
4b9f894d
CP
351
352 /* HACK */
353 var foo = function() { document.location = "/auth?logout=1"; };
354 foo.delay(500);
ffbb638d 355 }
2cd9e32d
CP
356 }
357});
358
359qwebirc.ui.NewLoginUI = new Class({
360 Extends: qwebirc.ui.QuakeNetUI,
6f2e4a37
CP
361 loginBox: function(callbackfn, initialNickname, initialChannels, autoConnect, autoNick) {
362 this.postInitialize();
c38a0240 363
e20e5a6b 364 var w = this.newCustomWindow("Connect", true, qwebirc.ui.WINDOW_CONNECT);
6f2e4a37
CP
365 var callback = function(args) {
366 w.close();
367 callbackfn(args);
368 };
369
2cad083e 370 qwebirc.ui.GenericLoginBox(w.lines, callback, initialNickname, initialChannels, autoConnect, autoNick, this.options.networkName);
6f2e4a37
CP
371 }
372});