]>
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-2019 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 getStatusWindow : function ( client
) {
121 return this . windows
. get ( this . getClientId ( client
)). get ( this . getWindowIdentifier ( client
, qwebirc
. ui
. WINDOW_STATUS
));
123 getActiveIRCWindow : function ( client
) {
124 if (! this . active
|| this . active
. type
== qwebirc
. ui
. WINDOW_CUSTOM
) {
125 return this . getStatusWindow ( client
);
130 __setActiveWindow : function ( window
) {
131 this . active
= window
;
133 renameWindow : function ( window
, name
) {
134 if ( this . getWindow ( window
. client
, window
. type
, name
))
137 var clientId
= this . getClientId ( window
. client
);
138 var index
= this . windowArray
. indexOf ( window
);
142 this . windows
. get ( clientId
). remove ( window
. identifier
);
144 var window
= this . windowArray
[ index
];
146 window
. identifier
= this . getWindowIdentifier ( window
. client
, window
. type
, window
. name
);
148 this . windows
. get ( clientId
). put ( window
. identifier
, this . windowArray
[ index
]);
151 this . updateTitle ( window
. name
+ " - " + this . options
. appTitle
);
153 window
. rename ( window
. name
);
156 selectWindow : function ( window
) {
158 this . active
. deselect ();
159 window
. select (); /* calls setActiveWindow */
160 this . updateTitle ( window
. name
+ " - " + this . options
. appTitle
);
162 updateTitle : function ( text
) {
163 document
. title
= text
;
165 nextWindow : function ( direction
) {
166 if ( this . windowArray
. length
== 0 || ! this . active
)
172 var index
= this . windowArray
. indexOf ( this . active
);
176 index
= index
+ direction
;
178 index
= this . windowArray
. length
- 1 ;
179 } else if ( index
>= this . windowArray
. length
) {
183 this . selectWindow ( this . windowArray
[ index
]);
185 prevWindow : function () {
188 __closed : function ( window
) {
190 this . active
= undefined ;
191 if ( this . windowArray
. length
== 1 ) {
192 this . windowArray
= [];
194 var index
= this . windowArray
. indexOf ( window
);
197 } else if ( index
== 0 ) {
198 this . selectWindow ( this . windowArray
[ 1 ]);
200 this . selectWindow ( this . windowArray
[ index
- 1 ]);
205 this . windowArray
= this . windowArray
. erase ( window
);
206 this . windows
. get ( this . getClientId ( window
. client
)). remove ( window
. identifier
);
209 this shouldn't be called by overriding classes!
210 they should implement their own!
211 some form of user input MUST be received before an
212 IRC connection is made, else users are going to get
213 tricked into getting themselves glined
215 loginBox : function ( callback
, initialNickname
, initialChannels
, autoConnect
, autoNick
) {
216 this . postInitialize ();
218 this . addCustomWindow ( "Connect" , qwebirc
. ui
. ConnectPane
, "connectpane" , {
219 initialNickname : initialNickname
, initialChannels : initialChannels
, autoConnect : autoConnect
, callback : callback
, autoNick : autoNick
,
220 uiOptions : this . options
221 }, qwebirc
. ui
. WINDOW_CONNECT
);
223 focusChange : function ( newValue
) {
224 var window_
= this . getActiveWindow ();
225 if ($ defined ( window_
))
226 window_
. focusChange ( newValue
);
228 oobMessage : function ( message
) {
229 var c
= message
. splitMax ( " " , 2 );
237 var d
= c
[ 1 ]. splitMax ( " " , 2 );
243 if ( command
== "SAY" ) {
244 var w
= this . getActiveIRCWindow ();
245 if ($ defined ( w
) && ( w
. type
== qwebirc
. ui
. WINDOW_CHANNEL
|| w
. type
== qwebirc
. ui
. WINDOW_QUERY
)) {
246 w
. client
. exec ( "/SAY " + args
);
253 qwebirc
. ui
. StandardUI
= new Class ({
254 Extends : qwebirc
. ui
. BaseUI
,
255 initialize : function ( parentElement
, windowClass
, uiName
, options
) {
256 this . parent ( parentElement
, windowClass
, uiName
, options
);
258 this . UICommands
= this . __build_menu_items ( options
);
260 this . __styleValues
= { hue : qwebirc
. ui
. DEFAULT_HUE
, saturation : 0 , lightness : 0 , textHue : null , textSaturation : null , textLightness : null };
261 if ($ defined ( this . options
. hue
)) this . __styleValues
. hue
= this . options
. hue
;
262 this . tabCompleter
= new qwebirc
. ui
. TabCompleterFactory ( this );
263 this . uiOptions
= new qwebirc
. ui
. DefaultOptionsClass ( this , options
. uiOptionsArg
);
264 this . customWindows
= new QHash ();
266 if ($ defined ( this . options
. saturation
)) this . __styleValues
. saturation
= this . options
. saturation
;
267 if ($ defined ( this . options
. lightness
)) this . __styleValues
. lightness
= this . options
. lightness
;
268 if ($ defined ( this . options
. tsaturation
)) this . __styleValues
. textSaturation
= this . options
. tsaturation
;
269 if ($ defined ( this . options
. tlightness
)) this . __styleValues
. textLightness
= this . options
. tlightness
;
271 if ($ defined ( this . options
. hue
)) { /* overridden in url */
272 /* ugh... this will go away when we add proper options for hue/sat/light for text and background */
273 this . uiOptions
. setValueByPrefix ( "STYLE_HUE" , this . __styleValues
. hue
);
275 this . __styleValues
. hue
= this . uiOptions
. STYLE_HUE
; /* otherwise copy from serialised store */
277 this . __styleValues
. textHue
= $ defined ( this . options
. thue
) ? this . options
. thue : this . __styleValues
. hue
;
279 document
. addEvent ( "keydown" , this . __handleHotkey
. bind ( this ));
281 __build_menu_items : function ( options
) {
283 var seenAbout
= null ;
285 for ( var i
= 0 ; i
< qwebirc
. ui
. UI_COMMANDS_P1
. length
; i
++)
286 r
. push ([ true , qwebirc
. ui
. UI_COMMANDS_P1
[ i
]]);
287 for ( var i
= 0 ; i
< options
. customMenuItems
. length
; i
++)
288 r
. push ([ false , options
. customMenuItems
[ i
]]);
289 for ( var i
= 0 ; i
< qwebirc
. ui
. UI_COMMANDS_P2
. length
; i
++)
290 r
. push ([ true , qwebirc
. ui
. UI_COMMANDS_P2
[ i
]]);
293 for ( var i
= 0 ; i
< r
. length
; i
++) {
294 var preset
= r
[ i
][ 0 ], c
= r
[ i
][ 1 ];
296 if ( c
[ 0 ] == "About qwebirc" ) { /* HACK */
300 } else if ( seenAbout
) {
307 r2
. push ([ c
[ 0 ], this [ c
[ 1 ] + "Window" ]. bind ( this )]);
309 r2
. push ([ c
[ 0 ], ( function ( c
) { return function () {
310 this . addCustomWindow ( c
[ 0 ], qwebirc
. ui
. URLPane
, "urlpane" , { url : c
[ 1 ]});
311 }. bind ( this ); }). call ( this , c
)]);
317 __handleHotkey : function ( x
) {
319 if (! x
. alt
&& ! x
. control
&& ! x
. shift
&& ! x
. meta
) {
320 if (( x
. key
== "backspace" || x
. key
== "/" ) && ! this . getInputFocused ( x
)) {
323 } else if (! x
. alt
|| x
. control
|| x
. meta
) {
325 } else if ( x
. key
== "a" || x
. key
== "A" ) {
327 var highestIndex
= - 1 ;
330 for ( var i
= 0 ; i
< this . windowArray
. length
; i
++) {
331 var h
= this . windowArray
[ i
]. hilighted
;
337 if ( highestIndex
> - 1 )
338 this . selectWindow ( this . windowArray
[ highestIndex
]);
339 } else if (( x
. key
>= '0' && x
. key
<= '9' ) && ! x
. shift
) {
342 number
= x
. key
- '0' ;
348 if ( number
>= this . windowArray
. length
)
351 this . selectWindow ( this . windowArray
[ number
]);
352 } else if (( x
. key
== "left" || x
. key
== "up" ) && ! x
. shift
) {
355 } else if (( x
. key
== "right" || x
. key
== "down" ) && ! x
. shift
) {
365 getInputFocused : function ( x
) {
366 if ($$( "input" ). indexOf ( x
. target
) == - 1 && $$( "textarea" ). indexOf ( x
. target
) == - 1 )
370 newCustomWindow : function ( name
, select
, type
) {
372 type
= qwebirc
. ui
. WINDOW_CUSTOM
;
374 var w
= this . newWindow ( qwebirc
. ui
. CUSTOM_CLIENT
, type
, name
);
375 w
. addEvent ( "close" , function ( w
) {
376 this . windows
. get ( qwebirc
. ui
. CUSTOM_CLIENT
). remove ( w
. identifier
);
380 this . selectWindow ( w
);
384 addCustomWindow : function ( windowName
, class_
, cssClass
, options
, type
) {
385 if (!$ defined ( options
))
388 if ( this . customWindows
. contains ( windowName
)) {
389 this . selectWindow ( this . customWindows
. get ( windowName
));
393 var d
= this . newCustomWindow ( windowName
, true , type
);
394 this . customWindows
. put ( windowName
, d
);
396 d
. addEvent ( "close" , function () {
397 this . customWindows
. remove ( windowName
);
401 d
. lines
. addClass ( "qwebirc-" + cssClass
);
403 var ew
= new class_ ( d
. lines
, options
);
404 ew
. addEvent ( "close" , function () {
410 embeddedWindow : function () {
411 this . addCustomWindow ( "Add webchat to your site" , qwebirc
. ui
. EmbedWizard
, "embeddedwizard" , { baseURL : this . options
. baseURL
, uiOptions : this . uiOptions
, optionsCallback : function () {
412 this . optionsWindow ();
415 optionsWindow : function () {
416 this . addCustomWindow ( "Options" , qwebirc
. ui
. OptionsPane
, "optionspane" , this . uiOptions
);
418 aboutWindow : function () {
419 this . addCustomWindow ( "About qwebirc" , qwebirc
. ui
. AboutPane
, "aboutpane" , this . uiOptions
);
421 urlDispatcher : function ( name
, window
) {
422 if ( name
== "embedded" )
423 return [ "a" , this . embeddedWindow
. bind ( this )];
425 if ( name
== "options" )
426 return [ "a" , this . optionsWindow
. bind ( this )];
428 /* doesn't really belong here */
429 if ( name
== "whois" ) {
430 return [ "span" , function ( nick
) {
431 if ( this . uiOptions
. QUERY_ON_NICK_CLICK
) {
432 window
. client
. exec ( "/QUERY " + nick
);
434 window
. client
. exec ( "/WHOIS " + nick
);
441 tabComplete : function ( element
, backwards
) {
442 this . tabCompleter
. tabComplete ( element
, backwards
);
444 resetTabComplete : function () {
445 this . tabCompleter
. reset ();
447 setModifiableStylesheet : function ( name
) {
448 this . __styleSheet
= new qwebirc
. ui
. style
. ModifiableStylesheet ( qwebirc
. global
. staticBaseURL
+ "css/" + ( QWEBIRC_DEBUG
? "debug/" : "" ) + name
+ qwebirc
. FILE_SUFFIX
+ ".mcss" );
449 this . setModifiableStylesheetValues ({});
451 setModifiableStylesheetValues : function ( values
) {
452 for ( var k
in values
)
453 this . __styleValues
[ k
] = values
[ k
];
455 if (!$ defined ( this . __styleSheet
))
458 var back
= { hue : this . __styleValues
. hue
, lightness : this . __styleValues
. lightness
, saturation : this . __styleValues
. saturation
};
460 if (!$ defined ( this . __styleValues
. textHue
) && !$ defined ( this . __styleValues
. textLightness
) && !$ defined ( this . __styleValues
. textSaturation
)) {
463 front
= { hue : Number ( this . __styleValues
. textHue
), lightness : Number ( this . __styleValues
. textLightness
), saturation : Number ( this . __styleValues
. textSaturation
)}
470 this . __styleSheet
. set ( function () {
471 var mode
= arguments
[ 0 ];
473 var t
= colours
[ arguments
[ 2 ]];
474 var x
= new Color ( arguments
[ 1 ]);
475 var c
= x
. setHue ( t
. hue
). setSaturation ( x
. hsb
[ 1 ] + t
. saturation
). setBrightness ( x
. hsb
[ 2 ] + t
. lightness
);
476 if ( c
== "255,255,255" ) /* IE confuses white with transparent... */
479 return "rgb(" + c
+ ")" ;
480 } else if ( mode
== "o" ) {
481 return this . uiOptions
[ arguments
[ 1 ]] ? arguments
[ 2 ] : arguments
[ 3 ];
487 qwebirc
. ui
. NotificationUI
= new Class ({
488 Extends : qwebirc
. ui
. StandardUI
,
489 initialize : function ( parentElement
, windowClass
, uiName
, options
) {
490 this . parent ( parentElement
, windowClass
, uiName
, options
);
492 this . __beeper
= new qwebirc
. ui
. Beeper ( this . uiOptions
);
493 this . __flasher
= new qwebirc
. ui
. Flasher ( this . uiOptions
);
494 this . __notifier
= new qwebirc
. ui
. Notifier ( this . uiOptions
);
496 this . cancelFlash
= this . __flasher
. cancelFlash
. bind ( this . __flasher
);
498 beep : function ( notification
) {
499 this . __beeper
. beep ( notification
);
501 notify : function ( title
, message
, callback
) {
502 this . __beeper
. beep ( true );
503 this . __flasher
. flash ();
504 this . __notifier
. notify ( title
, message
, callback
);
506 setNotifications : function ( value
) {
507 this . __notifier
. setEnabled ( value
);
509 updateTitle : function ( text
) {
510 if ( this . __flasher
. updateTitle ( text
))
513 focusChange : function ( value
) {
515 this . __flasher
. focusChange ( value
);
516 this . __notifier
. focusChange ( value
);
520 qwebirc
. ui
. QuakeNetUI
= new Class ({
521 Extends : qwebirc
. ui
. NotificationUI
,
522 urlDispatcher : function ( name
, window
) {
523 if ( name
== "qwhois" ) {
524 return [ "span" , function ( auth
) {
525 if ($ defined ( this . parentObject
. options
. accountWhoisCommand
))
526 this . client
. exec ( this . parentObject
. options
. accountWhoisCommand
+ auth
);
529 return this . parent ( name
, window
);
532 if (! qwebirc
. auth
. loggedin ( true )) {
533 this . getActiveWindow (). errorMessage ( "Not logged in!" );
536 if ( confirm ( "Log out?" )) {
537 this . clients
. each ( function ( k
, v
) {
538 v
. quit ( "Logged out" );
542 var foo = function () { document
. location
= "/auth?logout=1" ; };
548 qwebirc
. ui
. RootUI
= qwebirc
. ui
. QuakeNetUI
;
550 qwebirc
. ui
. RequestTransformHTML = function ( options
) {
551 var HREF_ELEMENTS
= {
555 var update
= options
. update
;
556 var onSuccess
= options
. onSuccess
;
558 var fixUp = function ( node
) {
559 if ( node
. nodeType
!= 1 )
562 var tagName
= node
. nodeName
. toUpperCase ();
563 if ( HREF_ELEMENTS
[ tagName
]) {
564 var attr
= node
. getAttribute ( "transform_attr" );
565 var value
= node
. getAttribute ( "transform_value" );
566 if ($ defined ( attr
) && $ defined ( value
)) {
567 node
. removeAttribute ( "transform_attr" );
568 node
. removeAttribute ( "transform_value" );
569 node
. setAttribute ( attr
, qwebirc
. global
. staticBaseURL
+ value
);
573 for ( var i
= 0 ; i
< node
. childNodes
. length
; i
++)
574 fixUp ( node
. childNodes
[ i
]);
577 delete options
[ "update" ];
578 options
. onSuccess = function ( tree
, elements
, html
, js
) {
579 var container
= new Element ( "div" );
580 container
. set ( "html" , html
);
584 while ( container
. childNodes
. length
> 0 ) {
585 var x
= container
. firstChild
;
586 container
. removeChild ( x
);
587 update
. appendChild ( x
);
592 return new Request
. HTML ( options
);