]>
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 qwebirc
. util
. __log = function ( x
) {
54 if ( typeof console
!= "undefined" )
56 this . getActiveWindow (). addLine ( null , x
);
60 newClient : function ( client
) {
61 client
. id
= String ( this . clientId
++);
62 client
. hilightController
= new qwebirc
. ui
. HilightController ( client
);
63 client
. addEvent ( "signedOn" , function () {
64 this . poller
= new qwebirc
. xdomain
. Poller ( this . oobMessage
. bind ( this ));
65 this . fireEvent ( "signedOn" , client
);
67 this . windows
. put ( client
. id
, new QHash ());
68 this . clients
. put ( client
. id
, client
);
69 var w
= this . newWindow ( client
, qwebirc
. ui
. WINDOW_STATUS
, "Status" );
71 if (! this . firstClient
) {
72 this . firstClient
= true ;
73 w
. addLine ( "" , "qwebirc v" + qwebirc
. VERSION
);
74 w
. addLine ( "" , "Copyright (C) 2008-2014 Chris Porter and the qwebirc project." );
75 w
. addLine ( "" , "http://www.qwebirc.org" );
76 w
. addLine ( "" , "Licensed under the GNU General Public License, Version 2." );
80 getClientId : function ( client
) {
81 if ( client
== qwebirc
. ui
. CUSTOM_CLIENT
) {
82 return qwebirc
. ui
. CUSTOM_CLIENT
;
87 getWindowIdentifier : function ( client
, type
, name
) {
88 if ( type
== qwebirc
. ui
. WINDOW_MESSAGES
)
90 if ( type
== qwebirc
. ui
. WINDOW_STATUS
)
93 if ( client
== qwebirc
. ui
. CUSTOM_CLIENT
) /* HACK */
96 return "_" + client
. toIRCLower ( name
);
98 newWindow : function ( client
, type
, name
) {
99 var w
= this . getWindow ( client
, type
, name
);
103 var wId
= this . getWindowIdentifier ( client
, type
, name
);
104 var w
= new this . windowClass ( this , client
, type
, name
, wId
);
105 this . windows
. get ( this . getClientId ( client
)). put ( wId
, w
);
106 this . windowArray
. push ( w
);
110 getWindow : function ( client
, type
, name
) {
111 var c
= this . windows
. get ( this . getClientId ( client
));
115 return c
. get ( this . getWindowIdentifier ( client
, type
, name
));
117 getActiveWindow : function () {
120 getActiveIRCWindow : function ( client
) {
121 if (! this . active
|| this . active
. type
== qwebirc
. ui
. WINDOW_CUSTOM
) {
122 return this . windows
. get ( this . getClientId ( client
)). get ( this . getWindowIdentifier ( client
, qwebirc
. ui
. WINDOW_STATUS
));
127 __setActiveWindow : function ( window
) {
128 this . active
= window
;
130 renameWindow : function ( window
, name
) {
131 if ( this . getWindow ( window
. client
, window
. type
, name
))
134 var clientId
= this . getClientId ( window
. client
);
135 var index
= this . windowArray
. indexOf ( window
);
139 this . windows
. get ( clientId
). remove ( window
. identifier
);
141 var window
= this . windowArray
[ index
];
143 window
. identifier
= this . getWindowIdentifier ( window
. client
, window
. type
, window
. name
);
145 this . windows
. get ( clientId
). put ( window
. identifier
, this . windowArray
[ index
]);
148 this . updateTitle ( window
. name
+ " - " + this . options
. appTitle
);
150 window
. rename ( window
. name
);
153 selectWindow : function ( window
) {
155 this . active
. deselect ();
156 window
. select (); /* calls setActiveWindow */
157 this . updateTitle ( window
. name
+ " - " + this . options
. appTitle
);
159 updateTitle : function ( text
) {
160 document
. title
= text
;
162 nextWindow : function ( direction
) {
163 if ( this . windowArray
. length
== 0 || ! this . active
)
169 var index
= this . windowArray
. indexOf ( this . active
);
173 index
= index
+ direction
;
175 index
= this . windowArray
. length
- 1 ;
176 } else if ( index
>= this . windowArray
. length
) {
180 this . selectWindow ( this . windowArray
[ index
]);
182 prevWindow : function () {
185 __closed : function ( window
) {
187 this . active
= undefined ;
188 if ( this . windowArray
. length
== 1 ) {
189 this . windowArray
= [];
191 var index
= this . windowArray
. indexOf ( window
);
194 } else if ( index
== 0 ) {
195 this . selectWindow ( this . windowArray
[ 1 ]);
197 this . selectWindow ( this . windowArray
[ index
- 1 ]);
202 this . windowArray
= this . windowArray
. erase ( window
);
203 this . windows
. get ( this . getClientId ( window
. client
)). remove ( window
. identifier
);
206 this shouldn't be called by overriding classes!
207 they should implement their own!
208 some form of user input MUST be received before an
209 IRC connection is made, else users are going to get
210 tricked into getting themselves glined
212 loginBox : function ( callback
, initialNickname
, initialChannels
, autoConnect
, autoNick
) {
213 this . postInitialize ();
215 this . addCustomWindow ( "Connect" , qwebirc
. ui
. ConnectPane
, "connectpane" , {
216 initialNickname : initialNickname
, initialChannels : initialChannels
, autoConnect : autoConnect
, networkName : this . options
. networkName
, callback : callback
, autoNick : autoNick
217 }, qwebirc
. ui
. WINDOW_CONNECT
);
219 focusChange : function ( newValue
) {
220 var window_
= this . getActiveWindow ();
221 if ($ defined ( window_
))
222 window_
. focusChange ( newValue
);
224 oobMessage : function ( message
) {
225 var c
= message
. splitMax ( " " , 2 );
233 var d
= c
[ 1 ]. splitMax ( " " , 2 );
239 if ( command
== "SAY" ) {
240 var w
= this . getActiveIRCWindow ();
241 if ($ defined ( w
) && ( w
. type
== qwebirc
. ui
. WINDOW_CHANNEL
|| w
. type
== qwebirc
. ui
. WINDOW_QUERY
)) {
242 w
. client
. exec ( "/SAY " + args
);
249 qwebirc
. ui
. StandardUI
= new Class ({
250 Extends : qwebirc
. ui
. BaseUI
,
251 UICommands : qwebirc
. ui
. UI_COMMANDS
,
252 initialize : function ( parentElement
, windowClass
, uiName
, options
) {
253 this . parent ( parentElement
, windowClass
, uiName
, options
);
255 this . __styleValues
= { hue : qwebirc
. ui
. DEFAULT_HUE
, saturation : 0 , lightness : 0 , textHue : null , textSaturation : null , textLightness : null };
256 if ($ defined ( this . options
. hue
)) this . __styleValues
. hue
= this . options
. hue
;
257 this . tabCompleter
= new qwebirc
. ui
. TabCompleterFactory ( this );
258 this . uiOptions
= new qwebirc
. ui
. DefaultOptionsClass ( this , options
. uiOptionsArg
);
259 this . customWindows
= new QHash ();
261 if ($ defined ( this . options
. saturation
)) this . __styleValues
. saturation
= this . options
. saturation
;
262 if ($ defined ( this . options
. lightness
)) this . __styleValues
. lightness
= this . options
. lightness
;
263 if ($ defined ( this . options
. tsaturation
)) this . __styleValues
. textSaturation
= this . options
. tsaturation
;
264 if ($ defined ( this . options
. tlightness
)) this . __styleValues
. textLightness
= this . options
. tlightness
;
266 if ($ defined ( this . options
. hue
)) { /* overridden in url */
267 /* ugh... this will go away when we add proper options for hue/sat/light for text and background */
268 this . uiOptions
. setValueByPrefix ( "STYLE_HUE" , this . __styleValues
. hue
);
270 this . __styleValues
. hue
= this . uiOptions
. STYLE_HUE
; /* otherwise copy from serialised store */
272 this . __styleValues
. textHue
= $ defined ( this . options
. thue
) ? this . options
. thue : this . __styleValues
. hue
;
274 document
. addEvent ( "keydown" , this . __handleHotkey
. bind ( this ));
276 __handleHotkey : function ( x
) {
278 if (! x
. alt
|| x
. control
) {
279 if (( x
. key
== "backspace" || x
. key
== "/" ) && ! this . getInputFocused ( x
)) {
282 } else if ( x
. key
== "a" || x
. key
== "A" ) {
284 var highestIndex
= - 1 ;
287 for ( var i
= 0 ; i
< this . windowArray
. length
; i
++) {
288 var h
= this . windowArray
[ i
]. hilighted
;
294 if ( highestIndex
> - 1 )
295 this . selectWindow ( this . windowArray
[ highestIndex
]);
296 } else if ( x
. key
>= '0' && x
. key
<= '9' ) {
299 number
= x
. key
- '0' ;
305 if ( number
>= this . windowArray
. length
)
308 this . selectWindow ( this . windowArray
[ number
]);
309 } else if ( x
. key
== "left" ) {
312 } else if ( x
. key
== "right" ) {
321 getInputFocused : function ( x
) {
322 if ($$( "input" ). indexOf ( x
. target
) == - 1 && $$( "textarea" ). indexOf ( x
. target
) == - 1 )
326 newCustomWindow : function ( name
, select
, type
) {
328 type
= qwebirc
. ui
. WINDOW_CUSTOM
;
330 var w
= this . newWindow ( qwebirc
. ui
. CUSTOM_CLIENT
, type
, name
);
331 w
. addEvent ( "close" , function ( w
) {
332 this . windows
. get ( qwebirc
. ui
. CUSTOM_CLIENT
). remove ( w
. identifier
);
336 this . selectWindow ( w
);
340 addCustomWindow : function ( windowName
, class_
, cssClass
, options
, type
) {
341 if (!$ defined ( options
))
344 if ( this . customWindows
. contains ( windowName
)) {
345 this . selectWindow ( this . customWindows
. get ( windowName
));
349 var d
= this . newCustomWindow ( windowName
, true , type
);
350 this . customWindows
. put ( windowName
, d
);
352 d
. addEvent ( "close" , function () {
353 this . customWindows
. remove ( windowName
);
357 d
. lines
. addClass ( "qwebirc-" + cssClass
);
359 var ew
= new class_ ( d
. lines
, options
);
360 ew
. addEvent ( "close" , function () {
366 embeddedWindow : function () {
367 this . addCustomWindow ( "Add webchat to your site" , qwebirc
. ui
. EmbedWizard
, "embeddedwizard" , { baseURL : this . options
. baseURL
, uiOptions : this . uiOptions
, optionsCallback : function () {
368 this . optionsWindow ();
371 optionsWindow : function () {
372 this . addCustomWindow ( "Options" , qwebirc
. ui
. OptionsPane
, "optionspane" , this . uiOptions
);
374 aboutWindow : function () {
375 this . addCustomWindow ( "About" , qwebirc
. ui
. AboutPane
, "aboutpane" , this . uiOptions
);
377 privacyWindow : function () {
378 this . addCustomWindow ( "Privacy policy" , qwebirc
. ui
. PrivacyPolicyPane
, "privacypolicypane" , this . uiOptions
);
380 feedbackWindow : function () {
381 this . addCustomWindow ( "Feedback" , qwebirc
. ui
. FeedbackPane
, "feedbackpane" , this . uiOptions
);
383 helpWindow : function () {
384 this . addCustomWindow ( "Help!" , qwebirc
. ui
. HelpPane
, "helppane" , this . uiOptions
);
386 urlDispatcher : function ( name
, window
) {
387 if ( name
== "embedded" )
388 return [ "a" , this . embeddedWindow
. bind ( this )];
390 if ( name
== "options" )
391 return [ "a" , this . optionsWindow
. bind ( this )];
393 /* doesn't really belong here */
394 if ( name
== "whois" ) {
395 return [ "span" , function ( nick
) {
396 if ( this . uiOptions
. QUERY_ON_NICK_CLICK
) {
397 window
. client
. exec ( "/QUERY " + nick
);
399 window
. client
. exec ( "/WHOIS " + nick
);
406 tabComplete : function ( element
) {
407 this . tabCompleter
. tabComplete ( element
);
409 resetTabComplete : function () {
410 this . tabCompleter
. reset ();
412 setModifiableStylesheet : function ( name
) {
413 this . __styleSheet
= new qwebirc
. ui
. style
. ModifiableStylesheet ( qwebirc
. global
. staticBaseURL
+ "css/" + ( QWEBIRC_DEBUG
? "debug/" : "" ) + name
+ qwebirc
. FILE_SUFFIX
+ ".mcss" );
414 this . setModifiableStylesheetValues ({});
416 setModifiableStylesheetValues : function ( values
) {
417 for ( var k
in values
)
418 this . __styleValues
[ k
] = values
[ k
];
420 if (!$ defined ( this . __styleSheet
))
423 var back
= { hue : this . __styleValues
. hue
, lightness : this . __styleValues
. lightness
, saturation : this . __styleValues
. saturation
};
425 if (!$ defined ( this . __styleValues
. textHue
) && !$ defined ( this . __styleValues
. textLightness
) && !$ defined ( this . __styleValues
. textSaturation
)) {
428 front
= { hue : Number ( this . __styleValues
. textHue
), lightness : Number ( this . __styleValues
. textLightness
), saturation : Number ( this . __styleValues
. textSaturation
)}
435 this . __styleSheet
. set ( function () {
436 var mode
= arguments
[ 0 ];
438 var t
= colours
[ arguments
[ 2 ]];
439 var x
= new Color ( arguments
[ 1 ]);
440 var c
= x
. setHue ( t
. hue
). setSaturation ( x
. hsb
[ 1 ] + t
. saturation
). setBrightness ( x
. hsb
[ 2 ] + t
. lightness
);
441 if ( c
== "255,255,255" ) /* IE confuses white with transparent... */
444 return "rgb(" + c
+ ")" ;
445 } else if ( mode
== "o" ) {
446 return this . uiOptions
[ arguments
[ 1 ]] ? arguments
[ 2 ] : arguments
[ 3 ];
452 qwebirc
. ui
. NotificationUI
= new Class ({
453 Extends : qwebirc
. ui
. StandardUI
,
454 initialize : function ( parentElement
, windowClass
, uiName
, options
) {
455 this . parent ( parentElement
, windowClass
, uiName
, options
);
457 this . __beeper
= new qwebirc
. ui
. Beeper ( this . uiOptions
);
458 this . __flasher
= new qwebirc
. ui
. Flasher ( this . uiOptions
);
459 this . __notifier
= new qwebirc
. ui
. Notifier ( this . uiOptions
);
461 this . cancelFlash
= this . __flasher
. cancelFlash
. bind ( this . __flasher
);
464 this . __beeper
. beep ();
466 notify : function ( title
, message
, callback
) {
467 this . __beeper
. beep ();
468 this . __flasher
. flash ();
469 this . __notifier
. notify ( title
, message
, callback
);
471 setBeepOnMention : function ( value
) {
473 this . __beeper
. soundInit ();
475 setNotifications : function ( value
) {
476 this . __notifier
. setEnabled ( value
);
478 updateTitle : function ( text
) {
479 if ( this . __flasher
. updateTitle ( text
))
482 focusChange : function ( value
) {
484 this . __flasher
. focusChange ( value
);
485 this . __notifier
. focusChange ( value
);
489 qwebirc
. ui
. QuakeNetUI
= new Class ({
490 Extends : qwebirc
. ui
. NotificationUI
,
491 urlDispatcher : function ( name
, window
) {
492 if ( name
== "qwhois" ) {
493 return [ "span" , function ( auth
) {
494 this . client
. exec ( "/MSG Q whois #" + auth
);
497 return this . parent ( name
, window
);
500 if (! qwebirc
. auth
. loggedin ())
502 if ( confirm ( "Log out?" )) {
503 this . clients
. each ( function ( k
, v
) {
504 v
. quit ( "Logged out" );
508 var foo = function () { document
. location
= qwebirc
. global
. dynamicBaseURL
+ "auth?logout=1" ; };
514 qwebirc
. ui
. RootUI
= qwebirc
. ui
. QuakeNetUI
;
516 qwebirc
. ui
. RequestTransformHTML = function ( options
) {
517 var HREF_ELEMENTS
= {
521 var update
= options
. update
;
522 var onSuccess
= options
. onSuccess
;
524 var fixUp = function ( node
) {
525 if ( node
. nodeType
!= 1 )
528 var tagName
= node
. nodeName
. toUpperCase ();
529 if ( HREF_ELEMENTS
[ tagName
]) {
530 var attr
= node
. getAttribute ( "transform_attr" );
531 var value
= node
. getAttribute ( "transform_value" );
532 if ($ defined ( attr
) && $ defined ( value
)) {
533 node
. removeAttribute ( "transform_attr" );
534 node
. removeAttribute ( "transform_value" );
535 node
. setAttribute ( attr
, qwebirc
. global
. staticBaseURL
+ value
);
539 for ( var i
= 0 ; i
< node
. childNodes
. length
; i
++)
540 fixUp ( node
. childNodes
[ i
]);
543 delete options
[ "update" ];
544 options
. onSuccess = function ( tree
, elements
, html
, js
) {
545 var container
= new Element ( "div" );
546 container
. set ( "html" , html
);
550 while ( container
. childNodes
. length
> 0 ) {
551 var x
= container
. firstChild
;
552 container
. removeChild ( x
);
553 update
. appendChild ( x
);
558 return new Request
. HTML ( options
);