AIR: Estilizando y extendiendo nuestras aplicaciones (CSS y Javascript)

NOTA: Es recomendable que antes hayas leído los siguientes artículos:
Hello AIR: desarrollo de aplicaciones usando AIR de forma sencilla
AIR: desarrollando y probando nuestras aplicaciones

Caminando sobre el aire

Hemos visto ya los conceptos básicos de AIR, el uso de las herramientas de desarrollo que vienen incluidas en el SDK de AIR, hablamos sobre seguridad y hasta probamos nuestra primer aplicación usando adl. En esta tercera entrega de la serie de desarrollo en AIR hablaremos un poco más sobre seguridad, como desarrollar haciendo uso de los sandboxes y como aplicar estilos y un poco de javascript a nuestras aplicaciones.

NOTA: Esta serie no intenta por ningún motivo ser una guía sobre CSS o Javascript. Se asume que el lector tiene conocimientos sobre los lenguajes, por tal motivo los códigos serán explicados sin profundizar demasiado y solo cuando el autor lo crea necesario. Si hay mucha demanda, podemos iniciar una serie sobre Javascript y CSS (manifestarlo en los comentarios).

Creando un cliente AIR para twitter

Antes de empezar, veamos un ejemplo muy sencillo, pero que espero nos suba el ánimo. Se trata de una aplicación que lo único que hace es conectarse a twitter y permitirnos actualizar nuestro estado. La aplicación no es muy útil y en ningún momento intenta competir con las aplicaciones ya existentes para twitter. Lo que es más, la aplicación no es pensada para su uso en la vida real, sino más bien para demostrar la sencillez con la que se puede interactuar con servicios como twitter a través de AIR y javascript haciendo uso de las APIs ofrecidas por estos servicios.

El XML:

<?xml version="1.0" encoding="utf-8" ?>
<application xmlns="http://ns.adobe.com/air/application/1.0">
<id>com.wordpress.imbuzu.TwitterClient</id>
<filename>TwitterClient</filename>
<name>Twitter Client</name>
<description>Un cliente simple para enviar mensajes a twitter.</description>
<version>0.1</version>
<initialWindow>
<content>TwitterClient.html</content>
<title>Twitter Client</title>
<systemChrome>standard</systemChrome>
<transparent>false</transparent>
<visible>true</visible>
<minimizable>true</minimizable>
<maximizable>true</maximizable>
<resizable>true</resizable>
</initialWindow>
</application>

El HTML, Javascript y CSS

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="es" lang="es">
<head>
<meta http-equiv="content-type" content="text/html; charset=utf-8" />
<title>Twitter Client</title>
<script type="text/javascript">
function msjOk(msj){
ok = msj.value.length <= 140 ? true : false;
return ok;
}

function hayMsj(msj){
ok = msj.value.length > 0 ? true : false;
return ok;
}
var form;

window.onload = function(){
form = document.getElementById('formulario');
msj = document.getElementById('mensaje');
error = document.getElementById('error');

form.onsubmit = function(){
if(!hayMsj(msj)){
error.innerHTML = "No hay mensaje para enviar";
return false;
}else if(!msjOk(msj)){
error.innerHTML = "Tu mensaje contiene más de 140 caracteres";
return false;
}else{
xhr = new XMLHttpRequest();
xhr.onreadystatechange = function(){
if(xhr.readyState == 4){
if(xhr.status == 200){
error.innerHTML = 'Twitter actualizado';
}else{
error.innerHTML = 'Ha ocurrido un error. Intenta de nuevo. <br /><b>Twitter Response<\/b> <br />' + xhr.responseText + "<br />Status code: <br />" + xhr.status;
}
}
}

xhr.open("POST", "http://twitter.com/statuses/update.xml", true, 'usuario', 'clave');
xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
xhr.send('status=' + escape(msj.value));
return false;
}
}
}
</script>
<style type="text/css">
body{
text-align: center;
}
h1{
margin: 0;
color: #FFF;
background-color: #0F0;
}
textarea{
width: 98%;
height: 50px;
}

#error{
color: #F00;
}
</style>
</head>
<body>
<div id="pantalla">
<h1>Twitter Client</h1>
<h2 id="error"></h2>
<form id="formulario">
<p>
<textarea id="mensaje" name="mensaje" rows="20" cols="10"></textarea>
</p>
<p>
<input type="submit" name="enviarTwit" value="enviar" />
</p>
</form>
</div>
</body>
</html>

Esta ocasión he incluido el HTML, CSS y Javascript en un mismo archivo. En la vida real es recomendable que se mantengan separados por cuestiones de mantenimiento.

Si copias y pegas esos dos bonches de código, al primero lo llamas TwitterClient.xml, al segundo TwitterClient.html. Los guardas en un folder llamado TwitterClient y los pruebas como vimos anteriormente, verás algo como esto:

Picture 3

La interfaz es de lo más sencilla y su funcionamiento aún más. Para poder hacer uso tendrás que cambiar lo siguiente antes de probar la aplicación:

xhr.open("POST", "http://twitter.com/statuses/update.xml", true, 'usuario', 'clave');

cambia usuario por tu nombre de usuario en twitter, por ejemplo el mío es imbuzu.
cambia clave por tu clave, por ejemplo la mía es: 0-0 pensaste que te la daría? jajaja.

Como ese es solo un ejemplo no me voy a tomar el tiempo para explicar su funcionamiento, pero en poco tiempo estaremos haciendo aplicaciones aún más avanzadas que esta.

Ahora, hablemos sobre cajas de arena.

Usando el application sandbox:

El application sandbox no presenta restricciones mientras se inicializa el código, es decir, antes del evento onload. Una vez se ha cargado la aplicación, sin embargo, la cosa es diferente. Algunas de las restricciones que puede encontrar son con la función eval, el uso de Function (nótese la F mayúscula), el uso de strings en setTimeout y setInterval, el pseudo protocolo javascript:, el uso de document.write, el uso de innerHTML está limitado a solo texto plano, se prohibe el uso de script.src para apuntar una etiqueta script a otro documento diferente al inicial y algunas restricciones en cuanto al uso de XMLHttpRequest de forma sincrónica. Tener en cuenta estas restricciones nos hará más fácil la vida y dará claves sobre algunos errores que podemos encontrar.

Usando el non-applicattion sandbox:

El código cargado en el non-application sandbox está sujeto a las mismas restricciones que en la web. Además, no tiene acceso a ninguna de las APIs de AIR

Creando un puente entre los dos sandboxes.

AIR nos brinda la posibilidad de crear una interfaz llamada Sandbox Bridge. Este Sandbox Bridge no es más que un puente que nos permite comunicación directa y vi-direccional a través de una API entre el application sandbox y el non-application sandbox. Su uso puede resultar extremadamente útil en algunos casos, ya que nos brinda la posibilidad de comunicar dos extremos de la aplicación que de otra manera son incomunicables. Por ahora basta con saber que existe dicha posibilidad. Ya veremos su uso más adelante.

Usando CSS:

CSS es, como en la web, el componente en nuestra bolsa que nos va a dar la posibilidad de darle una presentación y personalidad a nuestras aplicaciones. Una de las bondades ofrecidas por AIR tanto para CSS como para Javascript es que usa webkit, el motor de Safari. Al ser solo un motor para todos los sistemas operativos, no tenemos que preocuparnos por diferencias en cuento a la implementación de las propiedades, funciones y métodos. Si funciona en Safarí, es 99% probable que funcionará en AIR. Si funciona en tu computadora, funcionará de igual manera en cualquier otra aun cuando tenga un sistema operativo diferente.

Como mencioné hace un momento, es recomendable que el CSS se mantenga completamente aparte del HTML. Una de las características de este lenguaje es que ha sido pensado para funcionar desde fuera del documento que modifica gráficamente. Mantener nuestro CSS de forma separada del resto de la aplicación nos dará la oportunidad de poder modificarlo libremente sin tener que tocar ninguna otra cosa que no sea CSS puro.

Como ya mencioné, CSS en AIR no representa las limitaciones que muchas veces representa en la web, especialmente con navegadores como IE6 o IE en general. Esto es una ventaja enorme ya que podemos usar selectores de forma avanzada y hacer uso de pseudoselectores como :before y :after, además de propiedades extremadamente útiles como content. Una desventaja es que webkit no soporta CSS expressions (exclusivas de IE), pero claro, siempre hay un camino al rededor de esta situación.

Veamos un ejemplo de CSS en AIR.

Continuando con la aplicación AIRHelloWorld que construimos en la entrega anterior, procedamos de la siguiente manera:
1)Abre AIRHelloWorld.html
2)Agrega la siguiente linea justo después de

<title>AIRHelloWorld</title>:
<link rel="stylesheet" href="estilos.css" type="text/css" media="screen" />

3)Crea un nuevo archivo y guardalo con el nombre estilos.css en la misma carpeta donde tienes AIRHelloWorld.html y AIRHelloWorld.xml.
4)En el nuevo archivo pon lo siguiente:

body{
background-color: #CC6;
color: #FFF;
margin: 0px;
}

H1{
background-color: #9C3;
margin: 0;
height: 35px;
text-align: center;
}

p{
font-size: 1.5em;
padding: 5px;
border-bottom: 2px #CCC solid;
}

5)Prueba la aplicación usando adl y verás los cambios. La aplicación sigue sin hacer nada, pero ya tiene un formato y un estilo que la hacen ver mejor que antes. Puedes seguir jugando con CSS y probar. Es más, te invito a que estilices tu aplicación y nos muestres una captura de pantalla para ver como queda!

Usando Javascript:

Al igual que CSS, javascript también puede ser implementado en nuestras aplicaciones AIR. Como vimos hace un momento su funcionamiento depende mucho del sandbox en el que se ha cargado, pero la mayor parte del tiempo es muy similar al de la web. Veamos un sencillo ejemplo de como hacer que nuestros elementos “aparezcan” con un desvanecido de entrada.

1)Nuevamente modifica el archivo AIRHelloWorld.html agregando la siguiente linea después del enlace hacia la hoja de estilos que hiciste en el primer paso de la sección anterior sobre CSS:

<script type="text/javascript" src="difuminado.js"></script>

2)Crea un nuevo archivo y guárdalo como difuminado.js dentro de la misma carpeta de tu proyecto.
3)En el nuevo archivo introduce lo siguiente:

//función difuniado
//autor: Buzu
//fecha: agosto 10 de 2009
//primera revisión
//modificada para el tutorial de AIR en MDW
//por hacer: Agregar eventos onInit y onFin
function difuminado(elem, inOut, duracion){
var $elem = (typeof elem).toLowerCase() == 'string' ? document.getElementById(elem) : elem;
var $modo = inOut || 'entrada';
var $duracion = (duracion < 100 ? duracion * 1000 : duracion) || 2500;

if($modo == 'entrada'){
var $alfa = 0;
var $intervalo = setInterval(
function(){
if($alfa < 100){
$alfa += 100 / ($duracion/100);
$elem.style.opacity = $alfa/100;
}else{
$alfa = 100;
clearInterval($intervalo);
$elem.style.opacity = $alfa/100;
};
}, 100
);
}else if($modo == 'salida'){
var $alfa = 100;
var $intervalo = setInterval(
function(){
if($alfa > 0){
$alfa -= 100 / ($duracion/100);
$elem.style.opacity = $alfa/100;
}else{
$alfa = 0;
clearInterval($intervalo);
$elem.style.opacity = $alfa/100;
};
}, 100
);
}else{
return alert('El modo debe ser "entrada" o "salida"')
}
}

window.onload = function(){
difuminado('pantalla');
}

Esta es una función que yo ya tenía y que he modificado para este tutorial. Lo que hace es permitirnos hacer difuminados de entrada y salida. En este caso estamos aplicando un difuminado de entrada a nuestro elemento pantalla que es el que contiene todos los demás elementos. Guarda tu archivo y vuelve a probar la aplicación usando adl y verás como los elementos aparecen poco a poco.

Como ya dije, esta serie no pretende detenerse a explicar conceptos sobre Javascript, pero si tienes dudas sobre el código usado, eres bienvenido a escribirlas en los comentarios y con gusto te ayudaremos.

Como vez, el uso de javascript y CSS es muy similar al uso de estos elementos en la web. Una de las grandes ventajas es que ahora, en AIR, desarrollas para un solo motor de render y no para muchos como en la web.

Por último, si te apetece extender la aplicación de twitter y después compartir con nosotros tus resultados, eres totalmente bienvenido. Dejo el código abierto para su uso, aun que sea una base muy precaria.

2 thoughts on “AIR: Estilizando y extendiendo nuestras aplicaciones (CSS y Javascript)

  1. Saludos, me permito preguntar algo relativo a AIR, estoy desarrollando una app con js + html , hasta ahor atutto bene, pero se me ha ocurrido integrar google map, esta no conecta bien y m eimagino por lo que he buscado que tiene que ver con el uso del sandbox, sin embargo no me queda muy claro la descripción de la documentación, si me podrías dar una mano en eso.
    gracias

    carlos

    • Hola, sin ver tu code no puedo ayudarte. No se como es que estas contruyendo tu app ni como estas cargando los mapas ni cuales son los problemas que tienes. Intenta haciendo algunos logs manuales ya sea con alert o con log y fijate en los errores que te da. Lo mas probable es que si sean los sandobxes. Trabajar con ellos es un poco ‘tricky’ es cuestion de entender la logica de los sandboxes y despues todo es mas sencillo.

Comments are closed.