Pequeño juego en (puro) CSS – Selectores, jerarquias y animaciones

Hace un tiempo, estaba jugando en codepen.io intentando hacer una cara en css.
Luego, decidí darle un poco màs de vida, respondiendo a ciertos eventos.

ghosts

Simplemente agregando estilos distintos al :active de la cara en cuestion.

Una vez hecho esto, intente darle un poco de interacción con otros elementos. Algo que se logra fácilmente con pseudo selectores y jerarquia.

Por ejemplo:


.face:hover + .ghost .eye.right {
  display: none;
}

Estoy ocultaría el elemento de clase eye y right que sean hijos de un elemento con clase ghost que sea hermano de un elemento con clase face que posea el pseudo-selector hover. Es decir, ocultaría el ojo izquierdo del fantasma cuando nos paremos, con el mouse, arriba en la cara.

Para las animaciones, en principio había usado animations, pero luego lo cambie para usar, simplemente, transitions.
Lo importante a tener en cuenta con esto, es de tener cuidado de no animar atributos que modifiquen la caja del elemento que estamos animando (left, right, top, bottom, width, heigth, margin, padding). Cambiar, por ejemplo, el ancho (width) de un elemento, hace que el navegador tenga que recalcular la posición del elemento y de aquellos que se encuentran a su alrededor (reflow), lo cual es algo costoso y, normalmente, se nota una animación poco fluida.
Para estos casos, debemos valernos de la propiedad transform, la cual nos permite aplicar diferentes transformaciones a nuestro elemento, haciendo que el browser solo tenga que repintar el mismo, sin preocuparse por nada más.
Más información sobre reflows y repaints, pueden ver este articulo: http://www.stubbornella.org/content/2009/03/27/reflows-repaints-css-performance-making-your-javascript-slow/ o este, un poco más general sobre el funcionamiento del browser: http://www.html5rocks.com/en/tutorials/internals/howbrowserswork/

En fin, el ejemplo pueden verlo en este codepen: The Adventures of Mr. Ball
Es un simple juego en el que hay dos fantasmas escondidos en la pantalla. La cara reacciona a diferentes eventos (hover en los fantasmas, click en la cara y click en los fantasmas)

Mi primer webapp (En FirefoxOS)

Este post es un resumen de la charla, introductoria a FirefoxOS, que dí en el evento Hackaton Express.

Pueden ver los slides de la misma desde: http://tehsis.github.io/slides/

El título, posee FirefoxOS entre parentesís, debido a que, en realidad, las cosas que vamos a ver deberían funcionar en distintos browsers y/o tecnologías. FirefoxOS, como plataforma, es el medio por el cual Mozilla provee un stack completo para poder desarrollar este tipo de apps basadas en tecnologías web, asegurando la implementación de los estandares propuestos por las llamadas WebAPI.
Esto es lo que más me atrae de esta plataforma, pero vamos a dejar de lado esto y vamos a ver que es lo nuevo (y no tan nuevo) que nos ofrece.

Web…¿Apps?

Este concepto no es, para nada, nuevo. De hecho, desde la primer versión del iPhone (antes, quizá) podiamos tener sitios web que se guardaban como si fuesen una aplicación y su experiencia de usuario intentaba simular a las aplicaciónes nativas. Sin embargo, tanto iOS, Android y el resto de los dispositivos (Sacando, problablemente, algunas excepciones no muy populares) ofrecián una API limitada en comparación con la ofrecida por el SDK nátivo de la plataforma.
Ahora, vamos a llevar el concepto de webapp un paso más allá del simple hecho de tener “un sitio web con un acceso directo y que se vea sin los botones del navegador” a una aplicación que el usuario puede instalar, es independiente y puede funcionar offline.

Instalables

El usuario, puede instalar las webapps como cualquier otra. Para esto, la aplicación debe contar con un archivo denominado “manifest”, el cual le indica a nuestro “sistema operativo” algunos datos de la aplicación, como ser, el nombre, la descripción, los iconos, los permisos que requiere y algunos más.

Acá, podemos diferenciar 3 tipos de apps de acuerdo a los permisos que poseen.
Las primeras, que pueden ser “hosteadas”, es decir, servidas a través de un servidor web (valga la redundancia) o empaquetadas, en donde todo el contenido se encuentra en un “paquete” (un archivo zip, en el caso de FirefoxOS), pueden acceder a un numero limitado de recursos, como ser, la vibración del teléfono o las notificaciones.
El segundo tipo, son las privilegiadas. Que poseen acceso a recursos más “peligrosos” como la conexión de red o el Bluetooth y requieren estar aprobadas por el MarketPlace para funcionar.

Por último, tenemos las certificadas, las cuales vienen preinstaladas en el dispositivo, por ejemplo la aplicación para realizar llamadas.

Independientes

Cada app es su propio mundo. Esto quiere decir, entre otras cosas, que la aplicación A no puede acceder a las cookies de la aplicación B. Aún si estas cookies comparten el mismo dominio.

Para un ejemplo más claro, pensemos en una app que se identifique con Facebook. Por más que otra app también lo requiera, deberá hacerlo de forma independiente ya que no puede leer las cookies (y ningún otro recurso) de la otra (Mención aparte merecen las denominadas web activities).

Devices API

Esta es la parte que más me emociona de las webapps. Ya que gracias a ellas podemos interactuar de forma más cercana con nuestro dispositivo. Podemos, por ejemplo, hacer vibrar nuestro celular, usar las notificaciones del sistema, reaccionar a los cambios de luz, conocer nuestro nivel de bateria ó si el dispositivo esta enchufado y un largo etcetera. Cuestiones que antes se encontraban relegadas únicamente a las aplicaciones “nativas”.

Para un pequeño ejemplo, si tenes una notebook o un celular con sensor de luz, probá tapar la cámara frontal (o bien, apaga la luz)

En fin, podríamos estar un buen rato viendo ejemplos de webAPIs. Son fáciles de usar y, por la novedad que implica que nuestro browser sea “consciente del entorno” siempre resulta interesante verlos. Pero para eso, mejor veamos la documentación oficial y pasemos a la acción.

Desarrollando mi primer webapp

Para dejar las cosas un poco más en claro vamos a hacer, paso a paso, una pequeña webapp.

La idea, sera hacer una sencilla app que nos avise una vez transcurra una x cantidad de segundos.

Como dijimos desde un principio, no necesitamos otra cosa distinta a lo que usualmente manejamos en desarrollo web. De modo que, para empezar, vamos a crear tres archivios: index.html, alarm.js y alarm.css

Empecemos por index.html. Nuestra app va a contar de un elemento input para colocar los segundos y un boton que pondrá la alarma a sonar.

Como vemos, no hay nada extraño en este archivo. Quizá, haga falta prestar atención al atributo type del input, el cual es de tipo “number”, esto hara que ademas de permitir validaciones, si accedemos desde un celular, solo veremos un teclado númerico en vez de un teclado completo

Pasemos ahora al javascript, en el que nuevamente no veremos muchas sorpresas:

Simplemente, escuchamos el click al boton, el cual genera un timeout que muestra una alerta pasado el tiempo que ingresamos en el input.

Ahora bien, esto no tiene nada de novedoso. De hecho, casi todo esto podría funcionar, incluso, en Internet Explorer 6 (Bueno, en realidad no, ya que no teniamos addEventListener) y no hace uso de nada que haga que nuestro browser use el dispositivo sobre el cual esta funcionando.

Vamos entonces a hacer que, al pasar el tiempo en lugar de mostrar el alert, muestre una notifiación (lo cual hara uso de las notificaciones del sistema operativo sobre el cual esta funcionando) y vibre.

Nuestra, en extremo sencilla, aplicación ya va tomando forma. Pero para cumplir con la definición de webapp que vimos al principio, necesitamos que pueda instalarse. Para eso, lo primero que debemos hacer es crear un archivo manifest para nuestra app. Este archivo, escrito en JSON, le dara al sistema operativo, información sobre la aplicación, tal como el nombre de la misma, la descripción, datos del desarrollador, los permisos que necesita y otra serie de parametros. Un posible manifest para nuestra app podría ser:

Para instalarlo, vamos a hacer uso del objeto mozApp, el cual nos provee lo necesario para instalar la aplicación, reaccionar ente errores, etc. Como notaran por el prefijo moz, este solo funciona en Firefox.

Para hacer aún más facil esto, vamos a usar una pequeña libreria que arme. La misma se encargara de controlar si la aplicación puede, o no, ser instalada sin problemas o si ya se encuentra instalada en el sistema. La pueden conseguir de https://github.com/tehsis/webinstaller/archive/master.zip y la forma de usarla es bastante sencilla:


La libreria, ademas de manejar la instalación en sí, se encarga de colocar clases en el body de acuerdo al estado de la aplicación, forma que podamos decidir si mostrar o no el boton para instalarla o cualquier otro mensaje que se nos ocurra (más info en: https://github.com/tehsis/webinstaller).

Como ven, dentro del manifest, estoy especificando un ícono (de 64×64), el mismo lo podemos crear siguiendo estos guidelines: http://www.mozilla.org/en-US/styleguide/products/firefoxos/icons/
Este sera usado para acceder a nuestra aplicación, una vez instalada.

Si vamos ahora a nuestra aplicación y hacemos click en el botón de Instalar, Firefox nos preguntara si deseamos hacerlo. Si confirmamos, podremos acceder a la aplicación como si se tratase de una más (Vale aclarar que esto funcionará en Firefox ya sea para desktop, Android y/o FirefoxOS)

Por último, solo queda agregar algo de estilo a nuestra aplicación. ¡Y listo! Ya tenemos nuestra primer webapp que, ademas, podemos instalar.

Alarm

Pueden bajar el ejemplo completo desde https://github.com/tehsis/alarmexpress

Herramientas para desarrolladores

Seguramente, en el desarrollo de nuestra aplicación, especialmente si es una un poco más complicada que esta, necesitemos realizar pruebas y/o resolver bugs. Para ello, Mozilla ofrece diferentes herramientas que vamos a mencionar sin entrar en mayores detalles:

La primera, son las Herramientas de desarrollo de Firefox las cuales podemos acceder presionando “Ctrl + shift + I” en Linux y Windows ó “⌘ + shift + I” en OSX,

Estas herramientas, cuentan con la clasica consola Javascript, en la cual podemos ejecutar comandos, un depurador (debugger, para los amigos), visor de red (A partir de Firefox 23), editor de estilos y profiler.

Mediante el debugger, podemos deternos el algún punto especifico de nuestra aplicación, examinar las variables, así como el contexto, ejecutar paso a paso, etc.

Firefox Devtools

Algo interesante de Firefox, es que podemos conectar el debugger con Firefox para Android o bien con un dispositivo con FirefoxOS y hacer uso del mismo de forma remota. Es bastante sencillo y funciona muy bien. Solo debemos ir a about:config (desde la barra de direcciones) y activar el flag devtools.debugger.remote-enabled. Esto hara que se nos habilite la opción “connect” dentro de “Herramientas -> Herramientas de desarrollo” en Firefox (La úbicación puede variar, según el sistema operativo) luego debemos activar esta posibilidad en nuestro dispositivo. Para más información, les dejo un árticulo al respecto: Desarrollo web móvil – Inspeccionando webs en dispositivos moviles.

Segundo, vamos a nombrar al emulador de FirefoxOS, el cual se instala mediante una extensión de Firefox

Esta extensión, nos permite instalar nuestra app, indicandole el manifest, o bien cargandola como una app empaquetada a través del navegador de FirefoxOS o bien mediante el Marketplace ya que, en definitiva, se trata de un emulador de este sistema y podemos usarlo completamente.

Firefox OS Emulator

En resumen:

  • Una webapp es una app, que hace uso de las tecnologías web, pueden ser instalada por el usario y funcionar offline
  • Gracias a las Devices API, las aplicaciones web ahora pueden ser “conscientes” del dispositivo en el que funcionan y acceder a sus recursos.
  • Para poder dar un empuje a este ecosistema, Mozilla ofrece FirefoxOS como plataforma 100% web. Sin embargo, esperamos que las novedades que incluye en cuanto a programación, esten disponibles en todas las platadormas
  • Para más información, ya sea de FirefoxOS o cualquier tema relacionado al desarrollo web, no dejen de visitar el Mozilla Developer Network ó MDN

Desarrollo web móvil – Inspeccionando webs en dispositivos moviles

Creo que no hace falta aclarar que desde hace, relativamente, poco tiempo los dispositivos móviles (smartphones, tablets) se volvieron una de las principales fuentes de tráfico a sitios web.
Trabajar con los mismos suele ser engorroso, debido a que no contamos con las facilidades que tenemos en los entornos de escritorio.
Sin embargo, en la mayoría de los browsers modernos, es posible utilizar el inspector web de forma remota para poder debuggear nuestra aplicación en tiempo real.
A continuación, voy a recopilar los métodos para activar esta funcionalidad en los browsers más conocidos e iré actualizando el post en caso de encontrar otro browser.

Safari – iOS 6+

Para poder utilizar el inspector web remoto de Safari, necesitamos la última versión de este browser para escritorio, la cual no esta disponible para ninguna otra plataforma ademas de OSX (que novedad ¿no?)

Activar el inspector en iOS

Debemos dirigirnos a Settings -> Safari -> Advance y habilitar la opción Web Inspector

Activar la inspección remota en Safari

Abrimos las settings de Safari (cmd + ,) vamos a la pestaña Advance y marcamos Show develop menu in menu bar.

Ahora vamos a ver un nuevo menú en la barra superior llamado Develop.  Abrimos el sitio que queremos inspeccionar en el dispositivo iOS con Safari, hacemos click en ese menú y vamos a ver una opción con el nombre del mismo. Dentro veremos una lista de los sitios inspeccionables que tenemos abiertos. Clickeamos en él y tendremos el inspector abierto, pudiendo hacer (casi) todo lo que hacemos con el inspector web de Safari en el escritorio.

Firefox – Android

Para hacer esto, necesitamos Firefox 15+ (Tanto en nuestro escritorio como en Android)

Activar el inspector en Android

Abrimos Firefox , vamos a about:config y cambiamos las siguientes settings:

devtools.debugger.force-local -> false

devtools.debugger.remote-enabled -> true

Reiniciamos el browser (normalmente basta con apretar Home en nuestro dispositivo, pero puede que necesitemos Matar la aplicación usando algún task manager.

Activar el debugging remoto

Abrimos Firefox, en el dispositivo Android, vamos nuevamente a about:config, y cambiamos:

devtools.debugger.remote-enabled -> true.

Reiniciamos el browser y ahora podemos activar el debugger remoto desde el menu  Web developer.

Tenemos que indicar la ip de nuestro teléfono y el puerto (por defecto, 6000.  Se puede cambiar mediante la opción devtools.debugger.remote-port en about:config, desde el dispositivo.)

Chrome – Android

Para esto, necesitamos descargar el SDK de Android.

Habilitar el debugging web

Abrimos Chrome en nuestro dispositivo Android, vamos a Settings -> Developer Tools y marcamos Enable USB web debugging.

Forwardear las conexiones al puerto del debugger

Conectamos mediante USB nuestro dispositivo y nos aseguramos de tener activada la opción USB debugging dentro de las Developer options.

En nuestro escritorio, dentro de la carpeta que contiene al SDK de Android, vamos a ver otra llamada platform-tools y dentro un programa abd.

Ejecutamos: adb forward tcp:9222 localabstract:chrome_devtools_remote

Inspeccionar

Abrimos Chrome en nuestro escritorio y vamos a http://localhost:9222 ahí veremos una lista de las pestañas abiertas en el dispositivo.  Al hacer click en una de ellas se abrirá la ventana del inspector y podremos comenzar a trabajar.

Opera Mobile

Activar DragonFly en el escritorio

Abrimos Opera y vamos a Tools -> Advance -> Opera dragonFly en el menú superior.   Luego buscamos el icono de Remote debugging configuration en el panel de DragonFly, seleccionamos el puerto y hacemos click en apply.

Conectar el dispositivo

Abrimos Opera Mobile e introducimos opera:debug en la barra de direcciones. Luego debemos ingresar la ip del escritorio donde tenemos corriendo Dragonfly y el puerto. Una vez hecho veremos la confirmación de que la conexión se realizo de forma exitosa.

Hecho esto, podemos abrir cualquier url y seleccionarla mediante el icono de debugging context en Dragonfly.

Fuentes:

Curiosidades de javascript: Valores primitivos, null y undefined

Es normal escuchar a muchos desarrolladores decir que en javascript todo es un objeto. Esto en realidad es un malentendido, puesto que existen los llamados valores primitivos, strings, números y booleanos, además de dos valores especiales null y undefined

Veamos los valores primitivos. En principio, uno pensaría que son objetos, ya que podemos sin ningún problema acceder a algunos métodos de los mismos.

A primera vista, la variable foo (y por tanto, el string “bar”) es un objeto. Sin embargo, esto no es cierto. Lo que ocurre es que javascript envuelve los valores primitivos con objetos cada vez que queremos acceder a algún método y/o propiedad de los mismos. Dicho objeto, es destruido luego de la operación.

Intentar asignar 5 a la propiedad num de foo no arroja ningún tipo de error, puesto que al intentar acceder a dicha propiedad foo es envuelto en un objeto, pero luego este es destruido, por lo tanto, foo.num toma el valor undefined.

El tipo de objeto usado para envolver los valores primitivos, depende del tipo de valor. Así, los strings son envueltos por objetos String(), los numéricos por Number() y booleanos por Boolean().

Por último, no hay que confundir un valor primitivo string con un objeto del tipo String (creado mediante new String()), a pesar que puedan comportarse de forma similar (lo mismo ocurre para otros tipos de valores)

Veamos ahora que ocurre con los otros dos tipos de valores que no son objetos, undefined y null.

Cuando declaramos una variable (y no le asignamos ningún valor) esta posee el valor undefined. También es el valor que devuelve una función que no devuelve ningún valor explícito.

De acuerdo al standard Ecmascript 5, undefined es un valor primitivo de tipo undefined. Es decir, así como {false, true} son los posibles valores del tipo booleano, undefined es el único valor posible del tipo undefined.

Algo similar ocurre con null, ya que es el único valor posible para el tipo de datos null. Se utiliza para representar la ausencia intencionada de un valor. Es decir. Una variable va a valer null únicamente si es asignado de forma explícita.

Es importante tener en cuenta que ocurre al momento de comparar null o undefined con otros valores, ya sea porque utilizamos el operador == (en lugar de ===) o bien porque intentamos operar con valores de distinto tipo (Ej: 3 + null).

Cuando es evaluado como booleano, ambos devuelven false.

Al momento de intentar evaluarlos como número, undefined es evaluado como NaN

null, en cambio, es evaluado como 0+.

Por último, al intentar evaluarlos como string, cada uno equivale al string “undefined” o “null” respectivamente.

Hay que destacar que undefined es, también, una propiedad del objeto global (window, en los browsers) cuyo valor es undefined. De acuerdo al estandard Ecma, undefined es una variable que no puede ser escrita.
Sin embargo, en browsers antiguos (Ej: Firefox anterior a la versión 4) esto no era así y podíamos asignar cualquier valor a dicha propiedad, por lo que debemos tener esto en cuenta si pretendemos soportar dichos browsers.

Como última mención, podemos ver que si aplicamos el operador typeof, ocurre lo siguiente:

Es importante notar que null es tomado como de tipo object a pesar que si intentamos acceder a una propiedad de una variable null o undefined recibiremos un error de tipos.