]>
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-2017 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
, callback : callback
, autoNick : autoNick
,
217 uiOptions : this . options
218 }, qwebirc
. ui
. WINDOW_CONNECT
);
220 focusChange : function ( newValue
) {
221 var window_
= this . getActiveWindow ();
222 if ($ defined ( window_
))
223 window_
. focusChange ( newValue
);
225 oobMessage : function ( message
) {
226 var c
= message
. splitMax ( " " , 2 );
234 var d
= c
[ 1 ]. splitMax ( " " , 2 );
240 if ( command
== "SAY" ) {
241 var w
= this . getActiveIRCWindow ();
242 if ($ defined ( w
) && ( w
. type
== qwebirc
. ui
. WINDOW_CHANNEL
|| w
. type
== qwebirc
. ui
. WINDOW_QUERY
)) {
243 w
. client
. exec ( "/SAY " + args
);
250 qwebirc
. ui
. StandardUI
= new Class ({
251 Extends : qwebirc
. ui
. BaseUI
,
252 initialize : function ( parentElement
, windowClass
, uiName
, options
) {
253 this . parent ( parentElement
, windowClass
, uiName
, options
);
255 this . UICommands
= this . __build_menu_items ( options
);
257 this . __styleValues
= { hue : qwebirc
. ui
. DEFAULT_HUE
, saturation : 0 , lightness : 0 , textHue : null , textSaturation : null , textLightness : null };
258 if ($ defined ( this . options
. hue
)) this . __styleValues
. hue
= this . options
. hue
;
259 this . tabCompleter
= new qwebirc
. ui
. TabCompleterFactory ( this );
260 this . uiOptions
= new qwebirc
. ui
. DefaultOptionsClass ( this , options
. uiOptionsArg
);
261 this . customWindows
= new QHash ();
263 if ($ defined ( this . options
. saturation
)) this . __styleValues
. saturation
= this . options
. saturation
;
264 if ($ defined ( this . options
. lightness
)) this . __styleValues
. lightness
= this . options
. lightness
;
265 if ($ defined ( this . options
. tsaturation
)) this . __styleValues
. textSaturation
= this . options
. tsaturation
;
266 if ($ defined ( this . options
. tlightness
)) this . __styleValues
. textLightness
= this . options
. tlightness
;
268 if ($ defined ( this . options
. hue
)) { /* overridden in url */
269 /* ugh... this will go away when we add proper options for hue/sat/light for text and background */
270 this . uiOptions
. setValueByPrefix ( "STYLE_HUE" , this . __styleValues
. hue
);
272 this . __styleValues
. hue
= this . uiOptions
. STYLE_HUE
; /* otherwise copy from serialised store */
274 this . __styleValues
. textHue
= $ defined ( this . options
. thue
) ? this . options
. thue : this . __styleValues
. hue
;
276 document
. addEvent ( "keydown" , this . __handleHotkey
. bind ( this ));
278 __build_menu_items : function ( options
) {
280 var seenAbout
= null ;
282 for ( var i
= 0 ; i
< qwebirc
. ui
. UI_COMMANDS_P1
. length
; i
++)
283 r
. push ([ true , qwebirc
. ui
. UI_COMMANDS_P1
[ i
]]);
284 for ( var i
= 0 ; i
< options
. customMenuItems
. length
; i
++)
285 r
. push ([ false , options
. customMenuItems
[ i
]]);
286 for ( var i
= 0 ; i
< qwebirc
. ui
. UI_COMMANDS_P2
. length
; i
++)
287 r
. push ([ true , qwebirc
. ui
. UI_COMMANDS_P2
[ i
]]);
290 for ( var i
= 0 ; i
< r
. length
; i
++) {
291 var preset
= r
[ i
][ 0 ], c
= r
[ i
][ 1 ];
293 if ( c
[ 0 ] == "About qwebirc" ) { /* HACK */
297 } else if ( seenAbout
) {
304 r2
. push ([ c
[ 0 ], this [ c
[ 1 ] + "Window" ]. bind ( this )]);
306 r2
. push ([ c
[ 0 ], ( function ( c
) { return function () {
307 this . addCustomWindow ( c
[ 0 ], qwebirc
. ui
. URLPane
, "urlpane" , { url : c
[ 1 ]});
308 }. bind ( this ); }). call ( this , c
)]);
314 __handleHotkey : function ( x
) {
316 if (! x
. alt
&& ! x
. control
&& ! x
. shift
&& ! x
. meta
) {
317 if (( x
. key
== "backspace" || x
. key
== "/" ) && ! this . getInputFocused ( x
)) {
320 } else if (! x
. alt
|| x
. control
|| x
. meta
) {
322 } else if ( x
. key
== "a" || x
. key
== "A" ) {
324 var highestIndex
= - 1 ;
327 for ( var i
= 0 ; i
< this . windowArray
. length
; i
++) {
328 var h
= this . windowArray
[ i
]. hilighted
;
334 if ( highestIndex
> - 1 )
335 this . selectWindow ( this . windowArray
[ highestIndex
]);
336 } else if (( x
. key
>= '0' && x
. key
<= '9' ) && ! x
. shift
) {
339 number
= x
. key
- '0' ;
345 if ( number
>= this . windowArray
. length
)
348 this . selectWindow ( this . windowArray
[ number
]);
349 } else if (( x
. key
== "left" || x
. key
== "up" ) && ! x
. shift
) {
352 } else if (( x
. key
== "right" || x
. key
== "down" ) && ! x
. shift
) {
362 getInputFocused : function ( x
) {
363 if ($$( "input" ). indexOf ( x
. target
) == - 1 && $$( "textarea" ). indexOf ( x
. target
) == - 1 )
367 newCustomWindow : function ( name
, select
, type
) {
369 type
= qwebirc
. ui
. WINDOW_CUSTOM
;
371 var w
= this . newWindow ( qwebirc
. ui
. CUSTOM_CLIENT
, type
, name
);
372 w
. addEvent ( "close" , function ( w
) {
373 this . windows
. get ( qwebirc
. ui
. CUSTOM_CLIENT
). remove ( w
. identifier
);
377 this . selectWindow ( w
);
381 addCustomWindow : function ( windowName
, class_
, cssClass
, options
, type
) {
382 if (!$ defined ( options
))
385 if ( this . customWindows
. contains ( windowName
)) {
386 this . selectWindow ( this . customWindows
. get ( windowName
));
390 var d
= this . newCustomWindow ( windowName
, true , type
);
391 this . customWindows
. put ( windowName
, d
);
393 d
. addEvent ( "close" , function () {
394 this . customWindows
. remove ( windowName
);
398 d
. lines
. addClass ( "qwebirc-" + cssClass
);
400 var ew
= new class_ ( d
. lines
, options
);
401 ew
. addEvent ( "close" , function () {
407 embeddedWindow : function () {
408 this . addCustomWindow ( "Add webchat to your site" , qwebirc
. ui
. EmbedWizard
, "embeddedwizard" , { baseURL : this . options
. baseURL
, uiOptions : this . uiOptions
, optionsCallback : function () {
409 this . optionsWindow ();
412 optionsWindow : function () {
413 this . addCustomWindow ( "Options" , qwebirc
. ui
. OptionsPane
, "optionspane" , this . uiOptions
);
415 aboutWindow : function () {
416 this . addCustomWindow ( "About qwebirc" , qwebirc
. ui
. AboutPane
, "aboutpane" , this . uiOptions
);
418 feedbackWindow : function () {
419 this . addCustomWindow ( "Feedback" , qwebirc
. ui
. FeedbackPane
, "feedbackpane" , 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
);
499 this . __beeper
. beep ();
501 notify : function ( title
, message
, callback
) {
502 this . __beeper
. beep ();
503 this . __flasher
. flash ();
504 this . __notifier
. notify ( title
, message
, callback
);
506 setBeepOnMention : function ( value
) {
508 this . __beeper
. soundInit ();
510 setNotifications : function ( value
) {
511 this . __notifier
. setEnabled ( value
);
513 updateTitle : function ( text
) {
514 if ( this . __flasher
. updateTitle ( text
))
517 focusChange : function ( value
) {
519 this . __flasher
. focusChange ( value
);
520 this . __notifier
. focusChange ( value
);
524 qwebirc
. ui
. QuakeNetUI
= new Class ({
525 Extends : qwebirc
. ui
. NotificationUI
,
526 urlDispatcher : function ( name
, window
) {
527 if ( name
== "qwhois" ) {
528 return [ "span" , function ( auth
) {
529 if ($ defined ( this . parentObject
. options
. accountWhoisCommand
))
530 this . client
. exec ( this . parentObject
. options
. accountWhoisCommand
+ auth
);
533 return this . parent ( name
, window
);
536 if (! qwebirc
. auth
. loggedin ())
538 if ( confirm ( "Log out?" )) {
539 this . clients
. each ( function ( k
, v
) {
540 v
. quit ( "Logged out" );
544 var foo = function () { document
. location
= qwebirc
. global
. dynamicBaseURL
+ "auth?logout=1" ; };
550 qwebirc
. ui
. RootUI
= qwebirc
. ui
. QuakeNetUI
;
552 qwebirc
. ui
. RequestTransformHTML = function ( options
) {
553 var HREF_ELEMENTS
= {
557 var update
= options
. update
;
558 var onSuccess
= options
. onSuccess
;
560 var fixUp = function ( node
) {
561 if ( node
. nodeType
!= 1 )
564 var tagName
= node
. nodeName
. toUpperCase ();
565 if ( HREF_ELEMENTS
[ tagName
]) {
566 var attr
= node
. getAttribute ( "transform_attr" );
567 var value
= node
. getAttribute ( "transform_value" );
568 if ($ defined ( attr
) && $ defined ( value
)) {
569 node
. removeAttribute ( "transform_attr" );
570 node
. removeAttribute ( "transform_value" );
571 node
. setAttribute ( attr
, qwebirc
. global
. staticBaseURL
+ value
);
575 for ( var i
= 0 ; i
< node
. childNodes
. length
; i
++)
576 fixUp ( node
. childNodes
[ i
]);
579 delete options
[ "update" ];
580 options
. onSuccess = function ( tree
, elements
, html
, js
) {
581 var container
= new Element ( "div" );
582 container
. set ( "html" , html
);
586 while ( container
. childNodes
. length
> 0 ) {
587 var x
= container
. firstChild
;
588 container
. removeChild ( x
);
589 update
. appendChild ( x
);
594 return new Request
. HTML ( options
);