Index: /trunk/phpgwapi/js/expressolivre/expressolivre.js
===================================================================
--- /trunk/phpgwapi/js/expressolivre/expressolivre.js	(revision 2802)
+++ /trunk/phpgwapi/js/expressolivre/expressolivre.js	(revision 2874)
@@ -1,2 +1,22 @@
+//****c* ExpressoLivreAPI/ExpressoLivre
+// NAME
+//    ExpressoLivre
+//
+// DESCRIPTION
+//    Composto pelas classes utilizadas no ExpressoLivre
+//
+// AUTHOR
+//    Rodrigo Souza dos Santos
+//    |html <br /><a href="mailto:%72%6f%64%72%69%67%6f%2e%73%6f%75%7a%61%40%63%65%6c%65%70%61%72%2e%70%72%2e%67%6f%76%2e%62%72">&#114;&#111;&#100;&#114;&#105;&#103;&#111;&#46;&#115;&#111;&#117;&#122;&#97;&#64;&#99;&#101;&#108;&#101;&#112;&#97;&#114;&#46;&#112;&#114;&#46;&#103;&#111;&#118;&#46;&#98;&#114;</a>
+//    |html <br /><a href="mailto:%72%6f%64%72%69%67%6f%73%6f%75%7a%61%64%6f%73%73%61%6e%74%6f%73%40%67%6d%61%69%6c%2e%63%6f%6d">&#114;&#111;&#100;&#114;&#105;&#103;&#111;&#115;&#111;&#117;&#122;&#97;&#100;&#111;&#115;&#115;&#97;&#110;&#116;&#111;&#115;&#64;&#103;&#109;&#97;&#105;&#108;&#46;&#99;&#111;&#109;</a>
+//
+// NOTES
+//    A composiÃ§Ã£o possui instÃ¢ncias configuradas de forma a atender a maioria
+//    dos casos independente do mÃ³dulo.
+//
+//******
+// You can use this space for remarks that should not be included
+// in the documentation.
+//
 ( function( )
 {
@@ -14,4 +34,100 @@
 
 	var _loading = new Image( );
+
+	var _events_registred = {
+		"onload" : null,
+		"onunload" : null
+	};
+
+	function _events( )
+	{
+		return ( new function( )
+		{
+			//****m* ExpressoLivreAPI/ExpressoLivre/events/config
+			// NAME
+			//    config
+			//
+			// DESCRIPTION
+			//    Atribui uma aÃ§Ã£o a um evento em um objeto
+			//
+			// SYNOPSIS
+			//    config( Object, String, Function )
+			//
+			// INPUTS
+			//
+			// EXAMPLE
+			//    function myHandler( )
+			//    {
+			//        /*do something*/
+			//    }
+			//
+			//    ExpressoLivre.config( node, "onclick", myHandler );
+			//
+			//    ExpressoLivre.config( node, "onclick", function( )
+			//    {
+			//        /*do something*/
+			//    } );
+			//
+			//******
+			this.config = XEvents.add;
+			this.fire = ( new function( )
+			{
+				this.onload = function( )
+				{
+					if ( _events_registred.onload )
+					{
+						_events_registred.onload( );
+						_events_registred.onload = null;
+					}
+				};
+				this.onunload = function( )
+				{
+					if ( _events_registred.onunload )
+					{
+						_events_registred.onunload( );
+						_events_registred.onunload = null;
+					}
+				};
+			} );
+			this.onload = function( )
+			{
+				if ( arguments.length && arguments[ 0 ] == null )
+					return false;
+
+				if ( arguments[ 0 ].constructor == Boolean && arguments[ 0 ] == false )
+				{
+					_events_registred.onload = null;
+					return true;
+				}
+
+				if ( arguments[ 0 ].constructor == Function )
+				{
+					_events_registred.onload = arguments[ 0 ];
+					return true;
+				}
+
+				return false;
+			};
+			this.onunload = function( )
+			{
+				if ( arguments.length && arguments[ 0 ] == null )
+					return false;
+
+				if ( arguments[ 0 ].constructor == Boolean && arguments[ 0 ] == false )
+				{
+					_events_registred.onunload = null;
+					return true;
+				}
+
+				if ( arguments[ 0 ].constructor == Function )
+				{
+					_events_registred.onunload = arguments[ 0 ];
+					return true;
+				}
+
+				return false;
+			};
+		} );
+	}
 
 	function _form( )
@@ -64,5 +180,5 @@
 	function _path( )
 	{
-		return window.location.protocol + "//" + window.location.host + _configuration.url;
+		return _configuration.url;
 	}
 
@@ -85,11 +201,20 @@
 
 		if ( _language[ _phrase.toLowerCase( ) ] )
-			return _language[ _phrase.toLowerCase( ) ];
+			_phrase = _language[ _phrase.toLowerCase( ) ];
 		else
-			return _phrase + '*';
+			_phrase += '*';
+
+		if ( arguments.length > 1 )
+			for ( var j = 1; j < arguments.length; j++ )
+				if ( arguments[ j ] && arguments[ j ].constructor == String )
+					_phrase = _phrase.replace( "%" + j, arguments[ j ] );
+
+		return _phrase;
 	}
 
 	function _wait( )
 	{
+		_ExpressoLivre.events.fire.onunload( );
+
 		if ( _divAppboxHeader )
 			_divAppboxHeader.innerHTML = '';
@@ -105,23 +230,219 @@
 	}
 
-	function _ExpressoLivre( )
-	{
-		return ( new function( )
-		{
-			this.form = _form;
-			this.go = _go;
-			this.lang = _lang;
-			this.link = _link;
-			this.path = _path;
-			this.theme = _theme;
-			this.template = _template;
-			this.translate = _translate;
-		} );
-	}
-
-	window.ExpressoLivre = _ExpressoLivre( );
+	var _ExpressoLivre = ( new function( )
+	{
+		//****m* ExpressoLivreAPI/ExpressoLivre/events
+		// NAME
+		//    events
+		//
+		// DESCRIPTION
+		//    Realiza uma requisiÃ§Ã£o ao servidor.
+		//
+		// SYNOPSIS
+		//    events( Object )
+		//
+		// INPUTS
+		//
+		// EXAMPLE
+		//
+		//******
+		this.events = _events( );
+
+		//****m* ExpressoLivreAPI/ExpressoLivre/form
+		// NAME
+		//    form
+		//
+		// DESCRIPTION
+		//    Processa e envia um formulÃ¡rio, utilizando a URL do atributo "action".
+		//
+		// SYNOPSIS
+		//    form( Form )
+		//
+		// INPUTS
+		//    Form : referencia ao formulÃ¡rio a ser enviado.
+		//
+		// EXAMPLE
+		//    <form action="/url/to/action" onsubmit="ExpressoLivre.form( this );">
+		//
+		//    ExpressoLivre.form( document.forms[ 0 ] );
+		//
+		// NOTES
+		//    TODO: campo do tipo file nÃ£o Ã© tratado
+		//
+		//******
+		this.form = _form;
+
+		//****m* ExpressoLivreAPI/ExpressoLivre/go
+		// NAME
+		//    go
+		//
+		// DESCRIPTION
+		//    Realiza uma requisiÃ§Ã£o ao servidor.
+		//
+		// SYNOPSIS
+		//    go( Object )
+		//
+		// INPUTS
+		//    {
+		//        "access"  : String,
+		//        "handler" : Function,
+		//        [ "params" : String ]
+		//    }
+		//
+		// EXAMPLE
+		//    function myHandler( )
+		//    {
+		//        /*do something*/
+		//    }
+		//
+		//    ExpressoLivre.go( {
+		//        "access" : "module.class.method",
+		//        "handler" : myHandler
+		//    } );
+		//
+		//    ExpressoLivre.go( {
+		//        "access" : "module.class.method",
+		//        "handler" : function
+		//        {
+		//            /*do something*/
+		//        }
+		//    } );
+		//
+		//******
+		this.go = _go;
+
+		//****m* ExpressoLivreAPI/ExpressoLivre/lang
+		// NAME
+		//    lang
+		//
+		// DESCRIPTION
+		//    Carrega a traduÃ§Ã£o para o mÃ³dulo.
+		//
+		// SYNOPSIS
+		//    lang( String )
+		//
+		// INPUTS
+		//    String : nome do mÃ³dulo
+		//
+		// EXAMPLE
+		//    ExpressoLivre.lang( 'expressoAdmin1_2' );
+		//
+		//    ExpressoLivre.lang( 'expressoMail1_2' );
+		//
+		//    ExpressoLivre.lang( 'filemager' );
+		//
+		//******
+		this.lang = _lang;
+
+		//****m* ExpressoLivreAPI/ExpressoLivre/link
+		// NAME
+		//    link
+		//
+		// DESCRIPTION
+		//    Realiza uma requisiÃ§Ã£o ao servidor, trata o resultado interceptando os
+		//    links existentes e carrega os javascripts externos uma Ãºnica vez.
+		//
+		// SYNOPSIS
+		//    link( String link, [[Boolean cache], [String post]]  )
+		//
+		// INPUTS
+		//    String link   : URL da requisiÃ§Ã£o a ser realizada
+		//    Boolean cache : 'true' para manter cache do resultado da requisiÃ§Ã£o
+		//    String post   : query string que serÃ¡ enviada ao servidor
+		//
+		// EXAMPLE
+		//    ExpressoLivre.link( );
+		//
+		//******
+		this.link = _link;
+
+		//****m* ExpressoLivreAPI/ExpressoLivre/path
+		// NAME
+		//    path
+		//
+		// DESCRIPTION
+		//    Retorna a URL base do servidor ExpressoLivre.
+		//
+		// SYNOPSIS
+		//    String path( )
+		//
+		// RESULT
+		//    FQDN do servidor concatenado com o path do ExpressoLivre.
+		//
+		// EXAMPLE
+		//    ExpressoLivre.path( );
+		//
+		//******
+		this.path = _path;
+
+		//****m* ExpressoLivreAPI/ExpressoLivre/theme
+		// NAME
+		//    theme
+		//
+		// DESCRIPTION
+		//    Retorna o tema que corrente do usuÃ¡rio.
+		//
+		// SYNOPSIS
+		//    String theme( )
+		//
+		// RESULT
+		//    Nome do tema.
+		//
+		// EXAMPLE
+		//    ExpressoLivre.theme( );
+		//
+		//******
+		this.theme = _theme;
+
+		//****m* ExpressoLivreAPI/ExpressoLivre/template
+		// NAME
+		//    template
+		//
+		// DESCRIPTION
+		//    Retorna o template que corrente do usuÃ¡rio.
+		//
+		// SYNOPSIS
+		//    String template( )
+		//
+		// RESULT
+		//    Nome do template.
+		//
+		// EXAMPLE
+		//    ExpressoLivre.template( );
+		//
+		//******
+		this.template = _template;
+
+		//****m* ExpressoLivreAPI/ExpressoLivre/translate
+		// NAME
+		//    translate
+		//
+		// DESCRIPTION
+		//    Realiza a traduÃ§Ã£o para o idioma corrente.
+		//
+		// SYNOPSIS
+		//    String template( String phrase[, String ...] )
+		//
+		// INPUTS
+		//    String : frase a ser traduzida
+		//
+		// RESULT
+		//    Frase traduzida ou, em caso de nÃ£o haver a traduÃ§Ã£o, a frase com um
+		//    asterisco concatenado ao final.
+		//
+		// EXAMPLE
+		//    ExpressoLivre.translate( 'A phrase to translate' );
+		//
+		//******
+		this.translate = _translate;
+	} );
+	window.ExpressoLivre = _ExpressoLivre;
 
 	_xlink = new XLink( _path( ) );
 	_xlink.handler( {
+		"data" : function( _pData )
+		{
+			return ( _pData + '<script>ExpressoLivre.events.fire.onload( );</script>' );
+		},
 		"before" : _wait,
 		"after" : function( )
@@ -136,5 +457,5 @@
 
 	_xconnector = new XConnector( {
-		"path" : ExpressoLivre.path( ),
+		"path" : _path( ),
 		"controller" : "?menuaction="
 	} );
@@ -160,6 +481,6 @@
 			if ( _scripts.item( i ).getAttribute( 'src' ) != null )
 				_loaded[ _loaded.length ] = _scripts.item( i ).getAttribute( 'src' ).substr(
-					_path.length - 1,
-					_scripts.item( i ).getAttribute( 'src' ).indexOf( '?' ) - _path.length + 1
+					_path( ).length - 1,
+					_scripts.item( i ).getAttribute( 'src' ).indexOf( '?' ) - _path( ).length + 1
 				);
 
