]>
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
) {
243 if (( x
. key
== "backspace" || x
. key
== "/" ) && ! this . getInputFocused ( x
)) {
246 } else if ( x
. key
== "a" || x
. key
== "A" ) {
248 var highestIndex
= - 1 ;
251 for ( var i
= 0 ; i
< this . windowArray
. length
; i
++) {
252 var h
= this . windowArray
[ i
]. hilighted
;
258 if ( highestIndex
> - 1 )
259 this . selectWindow ( this . windowArray
[ highestIndex
]);
260 } else if ( x
. key
>= '0' && x
. key
<= '9' ) {
263 number
= x
. key
- '0' ;
269 if ( number
>= this . windowArray
. length
)
272 this . selectWindow ( this . windowArray
[ number
]);
273 } else if ( x
. key
== "left" ) {
276 } else if ( x
. key
== "right" ) {
285 getInputFocused : function ( x
) {
286 if ($$( "input" ). indexOf ( x
. target
) == - 1 && $$( "textarea" ). indexOf ( x
. target
) == - 1 )
290 newCustomWindow : function ( name
, select
, type
) {
292 type
= qwebirc
. ui
. WINDOW_CUSTOM
;
294 var w
= this . newWindow ( qwebirc
. ui
. CUSTOM_CLIENT
, type
, name
);
295 w
. addEvent ( "close" , function ( w
) {
296 this . windows
. get ( qwebirc
. ui
. CUSTOM_CLIENT
). remove ( w
. identifier
);
300 this . selectWindow ( w
);
304 addCustomWindow : function ( windowName
, class_
, cssClass
, options
) {
305 if (!$ defined ( options
))
308 if ( this . customWindows
. contains ( windowName
)) {
309 this . selectWindow ( this . customWindows
. get ( windowName
));
313 var d
= this . newCustomWindow ( windowName
, true );
314 this . customWindows
. put ( windowName
, d
);
316 d
. addEvent ( "close" , function () {
317 this . customWindows
. remove ( windowName
);
321 d
. lines
. addClass ( "qwebirc-" + cssClass
);
323 var ew
= new class_ ( d
. lines
, options
);
324 ew
. addEvent ( "close" , function () {
330 embeddedWindow : function () {
331 this . addCustomWindow ( "Add webchat to your site" , qwebirc
. ui
. EmbedWizard
, "embeddedwizard" , { baseURL : this . options
. baseURL
, uiOptions : this . uiOptions
, optionsCallback : function () {
332 this . optionsWindow ();
335 optionsWindow : function () {
336 this . addCustomWindow ( "Options" , qwebirc
. ui
. OptionsPane
, "optionspane" , this . uiOptions
);
338 aboutWindow : function () {
339 this . addCustomWindow ( "About" , qwebirc
. ui
. AboutPane
, "aboutpane" , this . uiOptions
);
341 privacyWindow : function () {
342 this . addCustomWindow ( "Privacy policy" , qwebirc
. ui
. PrivacyPolicyPane
, "privacypolicypane" , this . uiOptions
);
344 feedbackWindow : function () {
345 this . addCustomWindow ( "Feedback" , qwebirc
. ui
. FeedbackPane
, "feedbackpane" , this . uiOptions
);
347 helpWindow : function () {
348 this . addCustomWindow ( "Help!" , qwebirc
. ui
. HelpPane
, "helppane" , this . uiOptions
);
350 urlDispatcher : function ( name
, window
) {
351 if ( name
== "embedded" )
352 return [ "a" , this . embeddedWindow
. bind ( this )];
354 if ( name
== "options" )
355 return [ "a" , this . optionsWindow
. bind ( this )];
357 /* doesn't really belong here */
358 if ( name
== "whois" ) {
359 return [ "span" , function ( nick
) {
360 if ( this . uiOptions
. QUERY_ON_NICK_CLICK
) {
361 window
. client
. exec ( "/QUERY " + nick
);
363 window
. client
. exec ( "/WHOIS " + nick
);
370 tabComplete : function ( element
) {
371 this . tabCompleter
. tabComplete ( element
);
373 resetTabComplete : function () {
374 this . tabCompleter
. reset ();
376 setModifiableStylesheet : function ( name
) {
377 this . __styleSheet
= new qwebirc
. ui
. style
. ModifiableStylesheet ( qwebirc
. global
. staticBaseURL
+ "css/" + name
+ qwebirc
. FILE_SUFFIX
+ ".mcss" );
378 this . setModifiableStylesheetValues ({});
380 setModifiableStylesheetValues : function ( values
) {
381 for ( var k
in values
)
382 this . __styleValues
[ k
] = values
[ k
];
384 if (!$ defined ( this . __styleSheet
))
387 var back
= { hue : this . __styleValues
. hue
, lightness : this . __styleValues
. lightness
, saturation : this . __styleValues
. saturation
};
389 if (!$ defined ( this . __styleValues
. textHue
) && !$ defined ( this . __styleValues
. textLightness
) && !$ defined ( this . __styleValues
. textSaturation
)) {
392 front
= { hue : Number ( this . __styleValues
. textHue
), lightness : Number ( this . __styleValues
. textLightness
), saturation : Number ( this . __styleValues
. textSaturation
)}
399 this . __styleSheet
. set ( function () {
400 var mode
= arguments
[ 0 ];
402 var t
= colours
[ arguments
[ 2 ]];
403 var x
= new Color ( arguments
[ 1 ]);
404 var c
= x
. setHue ( t
. hue
). setSaturation ( x
. hsb
[ 1 ] + t
. saturation
). setBrightness ( x
. hsb
[ 2 ] + t
. lightness
);
405 if ( c
== "255,255,255" ) /* IE confuses white with transparent... */
408 return "rgb(" + c
+ ")" ;
409 } else if ( mode
== "o" ) {
410 return this . uiOptions
[ arguments
[ 1 ]] ? arguments
[ 2 ] : arguments
[ 3 ];
416 qwebirc
. ui
. NotificationUI
= new Class ({
417 Extends : qwebirc
. ui
. StandardUI
,
418 initialize : function ( parentElement
, windowClass
, uiName
, options
) {
419 this . parent ( parentElement
, windowClass
, uiName
, options
);
421 this . __beeper
= new qwebirc
. ui
. Beeper ( this . uiOptions
);
422 this . __flasher
= new qwebirc
. ui
. Flasher ( this . uiOptions
);
423 this . __notifier
= new qwebirc
. ui
. Notifier ( this . uiOptions
);
425 this . cancelFlash
= this . __flasher
. cancelFlash
. bind ( this . __flasher
);
428 this . __beeper
. beep ();
430 notify : function ( title
, message
, callback
) {
431 this . __beeper
. beep ();
432 this . __flasher
. flash ();
433 this . __notifier
. notify ( title
, message
, callback
);
435 setBeepOnMention : function ( value
) {
437 this . __beeper
. soundInit ();
439 setNotifications : function ( value
) {
440 this . __notifier
. setEnabled ( value
);
442 updateTitle : function ( text
) {
443 if ( this . __flasher
. updateTitle ( text
))
446 focusChange : function ( value
) {
448 this . __flasher
. focusChange ( value
);
449 this . __notifier
. focusChange ( value
);
453 qwebirc
. ui
. NewLoginUI
= new Class ({
454 Extends : qwebirc
. ui
. NotificationUI
,
455 loginBox : function ( callbackfn
, initialNickname
, initialChannels
, autoConnect
, autoNick
) {
456 this . postInitialize ();
458 /* I'd prefer something shorter and snappier! */
459 var w
= this . newCustomWindow ( "Connect" , true , qwebirc
. ui
. WINDOW_CONNECT
);
460 var callback = function ( args
) {
465 qwebirc
. ui
. GenericLoginBox ( w
. lines
, callback
, initialNickname
, initialChannels
, autoConnect
, autoNick
, this . options
. networkName
);
469 qwebirc
. ui
. QuakeNetUI
= new Class ({
470 Extends : qwebirc
. ui
. NewLoginUI
,
471 urlDispatcher : function ( name
, window
) {
472 if ( name
== "qwhois" ) {
473 return [ "span" , function ( auth
) {
474 this . client
. exec ( "/MSG Q whois #" + auth
);
477 return this . parent ( name
, window
);
480 if (! qwebirc
. auth
. loggedin ())
482 if ( confirm ( "Log out?" )) {
483 this . clients
. each ( function ( k
, v
) {
484 v
. quit ( "Logged out" );
488 var foo = function () { document
. location
= qwebirc
. global
. dynamicBaseURL
+ "auth?logout=1" ; };
494 qwebirc
. ui
. RootUI
= qwebirc
. ui
. QuakeNetUI
;
496 qwebirc
. ui
. RequestTransformHTML = function ( options
) {
497 var HREF_ELEMENTS
= {
501 var update
= options
. update
;
502 var onSuccess
= options
. onSuccess
;
504 var fixUp = function ( node
) {
505 if ( node
. nodeType
!= 1 )
508 var tagName
= node
. nodeName
. toUpperCase ();
509 if ( HREF_ELEMENTS
[ tagName
]) {
510 var attr
= node
. getAttribute ( "transform_attr" );
511 var value
= node
. getAttribute ( "transform_value" );
512 if ($ defined ( attr
) && $ defined ( value
)) {
513 node
. removeAttribute ( "transform_attr" );
514 node
. removeAttribute ( "transform_value" );
515 node
. setAttribute ( attr
, qwebirc
. global
. staticBaseURL
+ value
);
519 for ( var i
= 0 ; i
< node
. childNodes
. length
; i
++)
520 fixUp ( node
. childNodes
[ i
]);
523 delete options
[ "update" ];
524 options
. onSuccess = function ( tree
, elements
, html
, js
) {
525 var container
= new Element ( "div" );
526 container
. set ( "html" , html
);
530 while ( container
. childNodes
. length
> 0 ) {
531 var x
= container
. firstChild
;
532 container
. removeChild ( x
);
533 update
. appendChild ( x
);
538 return new Request
. HTML ( options
);