]>
jfr.im git - irc/quakenet/qwebirc.git/blob - 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 ;
8 qwebirc
. ui
. CUSTOM_CLIENT
= "custom" ;
9 qwebirc
. ui
. DEFAULT_HUE
= 210 ; /* nice blue */
11 qwebirc
. ui
. BaseUI
= new Class ({
13 initialize : function ( parentElement
, windowClass
, uiName
, options
) {
14 this . options
= options
;
16 this . windows
= new QHash ();
17 this . clients
= new QHash ();
18 this . windows
. put ( qwebirc
. ui
. CUSTOM_CLIENT
, new QHash ());
19 this . windowArray
= [];
20 this . windowClass
= windowClass
;
21 this . parentElement
= parentElement
;
22 this . parentElement
. addClass ( "qwebirc" );
23 this . parentElement
. addClass ( "qwebirc-" + uiName
);
24 this . firstClient
= false ;
25 this . commandhistory
= new qwebirc
. irc
. CommandHistory ();
28 this . windowFocused
= true ;
30 if ( Browser
. Engine
. trident
) {
31 var checkFocus = function () {
32 var hasFocus
= document
. hasFocus ();
33 if ( hasFocus
!= this . windowFocused
) {
34 this . windowFocused
= hasFocus
;
35 this . focusChange ( hasFocus
);
39 checkFocus
. periodical ( 100 , this );
41 var blur = function () { if ( this . windowFocused
) { this . windowFocused
= false ; this . focusChange ( false ); } }. bind ( this );
42 var focus = function () { if (! this . windowFocused
) { this . windowFocused
= true ; this . focusChange ( true ); } }. bind ( this );
44 /* firefox requires both */
46 document
. addEvent ( "blur" , blur
);
47 window
. addEvent ( "blur" , blur
);
48 document
. addEvent ( "focus" , focus
);
49 window
. addEvent ( "focus" , focus
);
52 newClient : function ( client
) {
53 client
. id
= String ( this . clientId
++);
54 client
. hilightController
= new qwebirc
. ui
. HilightController ( client
);
55 client
. addEvent ( "signedOn" , function () {
56 this . fireEvent ( "signedOn" , client
);
58 this . windows
. put ( client
. id
, new QHash ());
59 this . clients
. put ( client
. id
, client
);
60 var w
= this . newWindow ( client
, qwebirc
. ui
. WINDOW_STATUS
, "Status" );
62 if (! this . firstClient
) {
63 this . firstClient
= true ;
64 w
. addLine ( "" , "qwebirc v" + qwebirc
. VERSION
);
65 w
. addLine ( "" , "Copyright (C) 2008-2014 Chris Porter and the qwebirc project." );
66 w
. addLine ( "" , "http://www.qwebirc.org" );
67 w
. addLine ( "" , "Licensed under the GNU General Public License, Version 2." );
71 getClientId : function ( client
) {
72 if ( client
== qwebirc
. ui
. CUSTOM_CLIENT
) {
73 return qwebirc
. ui
. CUSTOM_CLIENT
;
78 getWindowIdentifier : function ( client
, type
, name
) {
79 if ( type
== qwebirc
. ui
. WINDOW_MESSAGES
)
81 if ( type
== qwebirc
. ui
. WINDOW_STATUS
)
84 if ( client
== qwebirc
. ui
. CUSTOM_CLIENT
) /* HACK */
87 return "_" + client
. toIRCLower ( name
);
89 newWindow : function ( client
, type
, name
) {
90 var w
= this . getWindow ( client
, type
, name
);
94 var wId
= this . getWindowIdentifier ( client
, type
, name
);
95 var w
= new this . windowClass ( this , client
, type
, name
, wId
);
96 this . windows
. get ( this . getClientId ( client
)). put ( wId
, w
);
97 this . windowArray
. push ( w
);
101 getWindow : function ( client
, type
, name
) {
102 var c
= this . windows
. get ( this . getClientId ( client
));
106 return c
. get ( this . getWindowIdentifier ( client
, type
, name
));
108 getActiveWindow : function () {
111 getActiveIRCWindow : function ( client
) {
112 if (! this . active
|| this . active
. type
== qwebirc
. ui
. WINDOW_CUSTOM
) {
113 return this . windows
. get ( this . getClientId ( client
)). get ( this . getWindowIdentifier ( client
, qwebirc
. ui
. WINDOW_STATUS
));
118 __setActiveWindow : function ( window
) {
119 this . active
= window
;
121 renameWindow : function ( window
, name
) {
122 if ( this . getWindow ( window
. client
, window
. type
, name
))
125 var clientId
= this . getClientId ( window
. client
);
126 var index
= this . windowArray
. indexOf ( window
);
130 this . windows
. get ( clientId
). remove ( window
. identifier
);
132 var window
= this . windowArray
[ index
];
134 window
. identifier
= this . getWindowIdentifier ( window
. client
, window
. type
, window
. name
);
136 this . windows
. get ( clientId
). put ( window
. identifier
, this . windowArray
[ index
]);
139 this . updateTitle ( window
. name
+ " - " + this . options
. appTitle
);
141 window
. rename ( window
. name
);
144 selectWindow : function ( window
) {
146 this . active
. deselect ();
147 window
. select (); /* calls setActiveWindow */
148 this . updateTitle ( window
. name
+ " - " + this . options
. appTitle
);
150 updateTitle : function ( text
) {
151 document
. title
= text
;
153 nextWindow : function ( direction
) {
154 if ( this . windowArray
. length
== 0 || ! this . active
)
160 var index
= this . windowArray
. indexOf ( this . active
);
164 index
= index
+ direction
;
166 index
= this . windowArray
. length
- 1 ;
167 } else if ( index
>= this . windowArray
. length
) {
171 this . selectWindow ( this . windowArray
[ index
]);
173 prevWindow : function () {
176 __closed : function ( window
) {
178 this . active
= undefined ;
179 if ( this . windowArray
. length
== 1 ) {
180 this . windowArray
= [];
182 var index
= this . windowArray
. indexOf ( window
);
185 } else if ( index
== 0 ) {
186 this . selectWindow ( this . windowArray
[ 1 ]);
188 this . selectWindow ( this . windowArray
[ index
- 1 ]);
193 this . windowArray
= this . windowArray
. erase ( window
);
194 this . windows
. get ( this . getClientId ( window
. client
)). remove ( window
. identifier
);
197 this shouldn't be called by overriding classes!
198 they should implement their own!
199 some form of user input MUST be received before an
200 IRC connection is made, else users are going to get
201 tricked into getting themselves glined
203 loginBox : function ( callback
, initialNickname
, initialChannels
, autoConnect
, autoNick
) {
204 qwebirc
. ui
. GenericLoginBox ( this . parentElement
, callback
, initialNickname
, initialChannels
, autoConnect
, autoNick
, this . options
. networkName
);
206 focusChange : function ( newValue
) {
207 var window_
= this . getActiveWindow ();
208 if ($ defined ( window_
))
209 window_
. focusChange ( newValue
);
213 qwebirc
. ui
. StandardUI
= new Class ({
214 Extends : qwebirc
. ui
. BaseUI
,
215 UICommands : qwebirc
. ui
. UI_COMMANDS
,
216 initialize : function ( parentElement
, windowClass
, uiName
, options
) {
217 this . parent ( parentElement
, windowClass
, uiName
, options
);
219 this . __styleValues
= { hue : qwebirc
. ui
. DEFAULT_HUE
, saturation : 0 , lightness : 0 , textHue : null , textSaturation : null , textLightness : null };
220 if ($ defined ( this . options
. hue
)) this . __styleValues
. hue
= this . options
. hue
;
221 this . tabCompleter
= new qwebirc
. ui
. TabCompleterFactory ( this );
222 this . uiOptions
= new qwebirc
. ui
. DefaultOptionsClass ( this , options
. uiOptionsArg
);
223 this . customWindows
= new QHash ();
225 if ($ defined ( this . options
. saturation
)) this . __styleValues
. saturation
= this . options
. saturation
;
226 if ($ defined ( this . options
. lightness
)) this . __styleValues
. lightness
= this . options
. lightness
;
227 if ($ defined ( this . options
. tsaturation
)) this . __styleValues
. textSaturation
= this . options
. tsaturation
;
228 if ($ defined ( this . options
. tlightness
)) this . __styleValues
. textLightness
= this . options
. tlightness
;
230 if ($ defined ( this . options
. hue
)) { /* overridden in url */
231 /* ugh... this will go away when we add proper options for hue/sat/light for text and background */
232 this . uiOptions
. setValueByPrefix ( "STYLE_HUE" , this . __styleValues
. hue
);
234 this . __styleValues
. hue
= this . uiOptions
. STYLE_HUE
; /* otherwise copy from serialised store */
236 this . __styleValues
. textHue
= $ defined ( this . options
. thue
) ? this . options
. thue : this . __styleValues
. hue
;
238 document
. addEvent ( "keydown" , this . __handleHotkey
. bind ( this ));
240 __handleHotkey : function ( x
) {
242 if (! x
. alt
&& ! x
. control
&& ! x
. shift
&& ! x
. meta
) {
243 if (( x
. key
== "backspace" || x
. key
== "/" ) && ! this . getInputFocused ( x
)) {
246 } else if (! x
. alt
|| x
. control
|| x
. meta
) {
248 } else if ( x
. key
== "a" || x
. key
== "A" ) {
250 var highestIndex
= - 1 ;
253 for ( var i
= 0 ; i
< this . windowArray
. length
; i
++) {
254 var h
= this . windowArray
[ i
]. hilighted
;
260 if ( highestIndex
> - 1 )
261 this . selectWindow ( this . windowArray
[ highestIndex
]);
262 } else if (( x
. key
>= '0' && x
. key
<= '9' ) && ! x
. shift
) {
265 number
= x
. key
- '0' ;
271 if ( number
>= this . windowArray
. length
)
274 this . selectWindow ( this . windowArray
[ number
]);
275 } else if (( x
. key
== "left" || x
. key
== "up" ) && ! x
. shift
) {
278 } else if (( x
. key
== "right" || x
. key
== "down" ) && ! x
. shift
) {
288 getInputFocused : function ( x
) {
289 if ($$( "input" ). indexOf ( x
. target
) == - 1 && $$( "textarea" ). indexOf ( x
. target
) == - 1 )
293 newCustomWindow : function ( name
, select
, type
) {
295 type
= qwebirc
. ui
. WINDOW_CUSTOM
;
297 var w
= this . newWindow ( qwebirc
. ui
. CUSTOM_CLIENT
, type
, name
);
298 w
. addEvent ( "close" , function ( w
) {
299 this . windows
. get ( qwebirc
. ui
. CUSTOM_CLIENT
). remove ( w
. identifier
);
303 this . selectWindow ( w
);
307 addCustomWindow : function ( windowName
, class_
, cssClass
, options
) {
308 if (!$ defined ( options
))
311 if ( this . customWindows
. contains ( windowName
)) {
312 this . selectWindow ( this . customWindows
. get ( windowName
));
316 var d
= this . newCustomWindow ( windowName
, true );
317 this . customWindows
. put ( windowName
, d
);
319 d
. addEvent ( "close" , function () {
320 this . customWindows
. remove ( windowName
);
324 d
. lines
. addClass ( "qwebirc-" + cssClass
);
326 var ew
= new class_ ( d
. lines
, options
);
327 ew
. addEvent ( "close" , function () {
333 embeddedWindow : function () {
334 this . addCustomWindow ( "Add webchat to your site" , qwebirc
. ui
. EmbedWizard
, "embeddedwizard" , { baseURL : this . options
. baseURL
, uiOptions : this . uiOptions
, optionsCallback : function () {
335 this . optionsWindow ();
338 optionsWindow : function () {
339 this . addCustomWindow ( "Options" , qwebirc
. ui
. OptionsPane
, "optionspane" , this . uiOptions
);
341 aboutWindow : function () {
342 this . addCustomWindow ( "About" , qwebirc
. ui
. AboutPane
, "aboutpane" , this . uiOptions
);
344 privacyWindow : function () {
345 this . addCustomWindow ( "Privacy policy" , qwebirc
. ui
. PrivacyPolicyPane
, "privacypolicypane" , this . uiOptions
);
347 feedbackWindow : function () {
348 this . addCustomWindow ( "Feedback" , qwebirc
. ui
. FeedbackPane
, "feedbackpane" , this . uiOptions
);
350 helpWindow : function () {
351 this . addCustomWindow ( "Help!" , qwebirc
. ui
. HelpPane
, "helppane" , this . uiOptions
);
353 urlDispatcher : function ( name
, window
) {
354 if ( name
== "embedded" )
355 return [ "a" , this . embeddedWindow
. bind ( this )];
357 if ( name
== "options" )
358 return [ "a" , this . optionsWindow
. bind ( this )];
360 /* doesn't really belong here */
361 if ( name
== "whois" ) {
362 return [ "span" , function ( nick
) {
363 if ( this . uiOptions
. QUERY_ON_NICK_CLICK
) {
364 window
. client
. exec ( "/QUERY " + nick
);
366 window
. client
. exec ( "/WHOIS " + nick
);
373 tabComplete : function ( element
, backwards
) {
374 this . tabCompleter
. tabComplete ( element
, backwards
);
376 resetTabComplete : function () {
377 this . tabCompleter
. reset ();
379 setModifiableStylesheet : function ( name
) {
380 this . __styleSheet
= new qwebirc
. ui
. style
. ModifiableStylesheet ( qwebirc
. global
. staticBaseURL
+ "css/" + name
+ qwebirc
. FILE_SUFFIX
+ ".mcss" );
381 this . setModifiableStylesheetValues ({});
383 setModifiableStylesheetValues : function ( values
) {
384 for ( var k
in values
)
385 this . __styleValues
[ k
] = values
[ k
];
387 if (!$ defined ( this . __styleSheet
))
390 var back
= { hue : this . __styleValues
. hue
, lightness : this . __styleValues
. lightness
, saturation : this . __styleValues
. saturation
};
392 if (!$ defined ( this . __styleValues
. textHue
) && !$ defined ( this . __styleValues
. textLightness
) && !$ defined ( this . __styleValues
. textSaturation
)) {
395 front
= { hue : Number ( this . __styleValues
. textHue
), lightness : Number ( this . __styleValues
. textLightness
), saturation : Number ( this . __styleValues
. textSaturation
)}
402 this . __styleSheet
. set ( function () {
403 var mode
= arguments
[ 0 ];
405 var t
= colours
[ arguments
[ 2 ]];
406 var x
= new Color ( arguments
[ 1 ]);
407 var c
= x
. setHue ( t
. hue
). setSaturation ( x
. hsb
[ 1 ] + t
. saturation
). setBrightness ( x
. hsb
[ 2 ] + t
. lightness
);
408 if ( c
== "255,255,255" ) /* IE confuses white with transparent... */
411 return "rgb(" + c
+ ")" ;
412 } else if ( mode
== "o" ) {
413 return this . uiOptions
[ arguments
[ 1 ]] ? arguments
[ 2 ] : arguments
[ 3 ];
419 qwebirc
. ui
. NotificationUI
= new Class ({
420 Extends : qwebirc
. ui
. StandardUI
,
421 initialize : function ( parentElement
, windowClass
, uiName
, options
) {
422 this . parent ( parentElement
, windowClass
, uiName
, options
);
424 this . __beeper
= new qwebirc
. ui
. Beeper ( this . uiOptions
);
425 this . __flasher
= new qwebirc
. ui
. Flasher ( this . uiOptions
);
426 this . __notifier
= new qwebirc
. ui
. Notifier ( this . uiOptions
);
428 this . cancelFlash
= this . __flasher
. cancelFlash
. bind ( this . __flasher
);
431 this . __beeper
. beep ();
433 notify : function ( title
, message
, callback
) {
434 this . __beeper
. beep ();
435 this . __flasher
. flash ();
436 this . __notifier
. notify ( title
, message
, callback
);
438 setBeepOnMention : function ( value
) {
440 this . __beeper
. soundInit ();
442 setNotifications : function ( value
) {
443 this . __notifier
. setEnabled ( value
);
445 updateTitle : function ( text
) {
446 if ( this . __flasher
. updateTitle ( text
))
449 focusChange : function ( value
) {
451 this . __flasher
. focusChange ( value
);
452 this . __notifier
. focusChange ( value
);
456 qwebirc
. ui
. NewLoginUI
= new Class ({
457 Extends : qwebirc
. ui
. NotificationUI
,
458 loginBox : function ( callbackfn
, initialNickname
, initialChannels
, autoConnect
, autoNick
) {
459 this . postInitialize ();
461 /* I'd prefer something shorter and snappier! */
462 var w
= this . newCustomWindow ( "Connect" , true , qwebirc
. ui
. WINDOW_CONNECT
);
463 var callback = function ( args
) {
468 qwebirc
. ui
. GenericLoginBox ( w
. lines
, callback
, initialNickname
, initialChannels
, autoConnect
, autoNick
, this . options
. networkName
);
472 qwebirc
. ui
. QuakeNetUI
= new Class ({
473 Extends : qwebirc
. ui
. NewLoginUI
,
474 urlDispatcher : function ( name
, window
) {
475 if ( name
== "qwhois" ) {
476 return [ "span" , function ( auth
) {
477 this . client
. exec ( "/MSG Q whois #" + auth
);
480 return this . parent ( name
, window
);
483 if (! qwebirc
. auth
. loggedin ())
485 if ( confirm ( "Log out?" )) {
486 this . clients
. each ( function ( k
, v
) {
487 v
. quit ( "Logged out" );
491 var foo = function () { document
. location
= qwebirc
. global
. dynamicBaseURL
+ "auth?logout=1" ; };
497 qwebirc
. ui
. RootUI
= qwebirc
. ui
. QuakeNetUI
;
499 qwebirc
. ui
. RequestTransformHTML = function ( options
) {
500 var HREF_ELEMENTS
= {
504 var update
= options
. update
;
505 var onSuccess
= options
. onSuccess
;
507 var fixUp = function ( node
) {
508 if ( node
. nodeType
!= 1 )
511 var tagName
= node
. nodeName
. toUpperCase ();
512 if ( HREF_ELEMENTS
[ tagName
]) {
513 var attr
= node
. getAttribute ( "transform_attr" );
514 var value
= node
. getAttribute ( "transform_value" );
515 if ($ defined ( attr
) && $ defined ( value
)) {
516 node
. removeAttribute ( "transform_attr" );
517 node
. removeAttribute ( "transform_value" );
518 node
. setAttribute ( attr
, qwebirc
. global
. staticBaseURL
+ value
);
522 for ( var i
= 0 ; i
< node
. childNodes
. length
; i
++)
523 fixUp ( node
. childNodes
[ i
]);
526 delete options
[ "update" ];
527 options
. onSuccess = function ( tree
, elements
, html
, js
) {
528 var container
= new Element ( "div" );
529 container
. set ( "html" , html
);
533 while ( container
. childNodes
. length
> 0 ) {
534 var x
= container
. firstChild
;
535 container
. removeChild ( x
);
536 update
. appendChild ( x
);
541 return new Request
. HTML ( options
);