Contenido

Drag & Drop + File API + XMLHttpRequest = El futuro de la subida de ficheros

15 dic

+ 10

Ya vimos que la beta 1 de Firefox 3.6 nos ofrecía una buena remesa de nuevos estándares y nuevas implementaciones que harán más interesante la experiencia del usuario frente al navegador. Para ilustrar una de ellas, Mozhacks ha implementado un pequeño ejemplo en el que podremos arrastrar imágenes desde nuestro escritorio diréctamente a nuestro navegador. Todo ello sobre Mozilla Firefox 3.6 Beta X, aprovechándose de la FileAPI (que ya hemos visto antes), el Drag & Drop externo y el archiconocido XMLHttpRequest (objeto culpable del Ajax).

drag_drop_file_api_firefox_3_6
(Ver Imagen)

Automáticamente al arrastrar las imágenes (permite multiselección) aparecerán en la página y así podremos visualizar las imágenes que vamos a subir antes de realmente subirlas. Esto es posible gracias a la nueva API de Ficheros que como vemos más abajo, es muy sencilla de usar:

// Leemos fichero binario
var reader = new FileReader();
reader.onload = function(e) {
 var bin = e.target.result;
 // bin is the binaryString
};
reader.readAsBinaryString(file);

// Subimos fichero como binario
var xhr = new XMLHttpRequest();
xhr.open("POST", "upload.php");
xhr.overrideMimeType('text/plain; charset=x-user-defined-binary');
xhr.sendAsBinary(bin);

Ver el código, no tiene desperdicio.

Histórico del nivel de uso de los navegadores web a lo largo de los últimos años

15 dic

+ 7

Microsiervos publica un interesante enlace en el que nos muestra mediante un interesante gráfico circular (en Flash) la evolución del uso de los diferentes navegadores web a lo largo de los últimos años. Pese a que se vé mucho Azul(Internet Explorer), el Naranja(Firefox) no pasa desapercibido. Los datos han sido obtenidos de la W3CSchools.

Las Meninas en 3D gracias a CSS

15 dic

+ 4

Román Cortes nos vuelve a mostrar el potencial de CSS, primero fué un Homer Simpson mediante CSS Art y ahora nos muestras Las Meninas de Velázquez como nunca las habíamos visto, en 3D con un efecto similar al ofrecidor por Parallax pero sin Javascript

meninas_css
(Ver Imagen)

Via / Demo

RightJS es entre 6-8 veces más rápido que jQuery

13 dic

+ 15

Hace unos meses vimos que jQuery era el framework JS más lento de los probados con TaskSpeed (un test masivo sobre frameworks JS). Ahora la versión 1.5 de RightJS, deja al framework desarrollado por John Resig a la altura del betún demostrando que és hasta 8 veces más rápido que jQuery.

Google Chrome

chrome
(Ver Imagen)

Además vemos como la versión 1.4 alpha 1, recien anunciada, mejora el tiempo de respuesta algo pero no lo suficiente para competir con RightJS en alguna de las prueabas realizadas.

Mozilla Firefox 3.5.5

ff
(Ver Imagen)

También es interesante ver en las imágenes que sobre Google Chrome, RightJS llega a ser hasta un 740% más rápido (jQuery 1.3.2) frente a los resultados en Firefox 3.5 en el que vemos que la diferencia solo es de 333% con la misma versión de jQuery, será por que John Resig trabaja en Mozilla :D

Actualizo:

Grabriel en uno de los comentarios nos pasa la url de donde se ha realizado el test. Con la aparición de la versión 1.5.0 de RightJS se decidió enfrentear con la aplicación TaskSpeed (que se encarga de testear los aspecto más comunes de los frameworks JS) esta nueva versión con la de los principales frameworks, obteniendo unos tiempos como vemos en las imágenes anteriores.

Despues nos muestra un par de optimizaciones para conseguir un tiempo similar al ofrecido por RightJS (343ms jQuery vs 80ms RightJS).

"make": function(){
	for(var i = 0; i<250; i++){
 	document.body.appendChild(
 		$(
 		"<ul id='setid" + i + "' class='fromcode'>"+
 		"<li>one</li>"+
 		"<li>two</li>"+
 		"<li>three</li>"+
 		"</ul>"
 		)[0]
 	);
 	}
 	return $("ul.fromcode").length;
}

Como podemos ver el código que deberíamos usar para poder acercarnos a ese tiempo, debemos prescindir de todo el jQuery posible, basando nuestro Script en Javascript puro y duro.

"make": function(){
	var elements = '<div>';
 	for(var i = 0; i<250; i++){
 		elements = elements+
 			"<ul id='setid" + i + "' class='fromcode'>"+
 			"<li>one</li>"+
 			"<li>two</li>"+
 			"<li>three</li>"+
 			"</ul>";
 		}
 		$(elements+'</div>')
 		.children()
 		.each(function() {
 			document.body.appendChild(this);
 			});
 return $("ul.fromcode").length;
}

Aclaración

Evidentemente un Framework Javascript no se evalua únicamente por la velocidad de ejecución, sinó que hay factores igual o más importantes, como la documentación, comunidad y compatibilidad con navegadores. Este estudio, únicamente debe servir para detectar este problema y conocerlo para poder encontrarle solución en caso de toparnos con este problema.

Lawnchair, almacenamiento DOM mediante JSON

12 dic

+ 3

Lawnchair es un librería que nos permite almacenar en el clientes datos en formato JSON, ideal para navegadores móviles basados en Webkit que nos permitirá aligerar el peso de una forma simple y elegante.

var people = new Lawnchair('people');

/* GRABAMOS */

// Grabamos un elemento
var me = {name:'brian'};
people.save(me);

// Grabamos un elemento de forma asíncrona
people.save({name:'frank'}, function(r) {
 console.log(r);
});

// Especificamos nuestra propia clave a nuestro elemento
people.save({key:'whatever', name:'dracula'});

/* CARGAMOS */

// Recogemos el elemento
people.get(me.key, function(r){
 console.log(r);
});

// Recupera todos los elementos en forma array
people.all(function(r){
 console.log(r);
});

// Sintaxis corto para recuperar todos los elementos
people.all('console.log(r)');

Como podemos ver la sintaxis es realmente sencilla de usar, ideal para deshacernos de esas cookies anticuadas de nuestras aplicaciones.

Ver código fuente. / Descargar

MooTools Forge, repositorio de plugins

12 dic

+ 0

Siempre he dicho que la única pega de MooTools es la falta de plugins disponibles en comparación con jQuery. Los desarrolladores del framework, son conscientes de ello y por ese motivo lanzan Forge, un repositorio de plugins donde buscar herramientas desarrolladas para MooTools

mootools.forge
(Ver Imagen)

Como valor añadido, nos ofrece información sobre las dependencias de cada plugin, para así poder ajustar nuestra versión del framework a las necesidades del plugin. Al igual, que la documentación necesaria para hacerlo funcionar.

Actualmente, la actividad es bastante baja, pero espero que poco a poco el repositorio crezca y ofrezca más y mejores plugins, que podamos utilizar.

W3C Capture API, ampliando los periféricos de entrada en la web

9 dic

+ 1

Si Google (o cualquiera) quiere hacer un sistema operativo basado en el navegador, tendrá que empezar a tener en cuenta el nuevo borrador que la W3C que nos permitirá, ampliar el número de periféricos de entrada desde la propia web.

El borrador, especifica una documentación sobre la interconexión de periféricos como la cámara o el micrófono para interactuar con nuestras webs desde Javascript.

var container = document.createElement("div");
document.body.appendChild(container);

var screenWidth = window.innerWidth;

function successCallback(data) {
  for (var i in data) {
    var img = document.createElement("img");
    img.src = data[i].uri;
    if (data[i].format.width > screenWidth) {
      img.style.width = screenWidth + "px";
      img.style.height = (data[i].format.height/data[i].format.width)*screenWidth + "px";
    }
    container.appendChild(img);
  }
}

function errorCallback(err) {
  alert(err.message + " (" + err.code + ")");
}

transactionId = navigator.device.captureImage(successCallback, 1, errorCallback);

Por el momento, ningún navegador nos permitirá usar esta especificación, pero llegado el momento será posible subir imágenes directamente desde nuestra cámara o grabar nuestros mensajes directamente desde una página web.

var summary;
var formats = navigator.device.supportedImageFormats;

for (var key in formats) {
summary += key + ": " + formats[key] + "\n";
}

alert(summary);

Dependiendo de la cámara del usuario podremos incluso detectar los formatos de imágenes que permite obtener. Es una lástima que estas implemententaciones vayan tan lentas y que para poder disfrutar de ellas tengamos que esperar tantos años.

Via

Jaml, bonita forma de generar HTML desde Javascript

7 dic

+ 6

Quizás lo más laborioso y repetitivo de Javascript es la creación de elementos DOM, por ello, son muchas las herramientas que hemos visto para generar esta tarea, incluso montamos una función (create()) que nos permitía crear estos elementos más fácilmente.

Jaml, es una implementación más que permite generar fácilmente estos elementos DOM, usando una estructura muy clara nos permite generar un código realmente limpio.

// Javascript
div(
 h1({cls: 'titulo'}"Some title"),
 p("Some exciting paragraph text"),
 br(),
 ul(
   li("First item"),
   li("Second item"),
   li("Third item")
 )
);

// HTML generado
<div>
 <h1 class="titulo">Some title</h1>
 <p>Some exciting paragraph text</p>
 <br />
 <ul>
   <li>First item</li>
   <li>Second item</li>
   <li>Third item</li>
 </ul>
</div>

Además, disponemos de una serie de métodos que nos permite generar templates que podemos usar pasándole un objeto para personalizar la salida.

// Registramos la plantilla
Jaml.register('product', function(product) {
 div({cls: 'product'},
   h1(product.title),
   p(product.description),
   img({src: product.thumbUrl}),
   a({href: product.imageUrl}, 'View larger image'),
   form(
    label({'for': 'quantity'}, "Quantity"),
    input({type: 'text', name: 'quantity', id: 'quantity', value: 1}),
    input({type: 'submit', value: 'Add to Cart'})
   )
 );
});

// Cargamos el objeto
var bsg = {
 title      : 'Battlestar Galactica DVDs',
 thumbUrl   : 'thumbnail.png',
 imageUrl   : 'image.png',
 description: 'Best. Show. Evar.'
};

// Cargamos el template con el objeto generado
Jaml.render('product', bsg);

// Resultado
<div>
 <h1>Battlestar Galactica DVDs</h1>
 <p>Best. Show. Evar.</p>
 <img src="thumbnail.png" />
 <a href="image.png">View larger image</a>
 <form>
   <label for="quantity">Quantity</label>
   <input type="text" name="quantity" id="quantity" value="1"></input>
   <input type="submit" value="Add to Cart"></input>
 </form>
</div>

Sin duda, una forma cómoda y util que podemos tener en cuenta.

WpMooSnow, ponle nieve a tu WordPress con MooTools

4 dic

+ 8

Sampedro de RutaRelativa desarrolla un plugin para WordPress que nos permite incluir nieve cayendo en nuestro blog. Algo muy interesante para las fechas que se acercan.[Demo][Descargar]

Truco del campo oculto antispam para WordPress más fácil todavía

4 dic

+ 13

Este artículo hace ya más de un año que comencé a escribirlo y hoy que he tenido unos minutos para repasarlo y modificar un poco el código lo termino.

Hace ya mucho tiempo, Jose Ramón (Manz) publicó en Emezeta un sistema bastante ingenioso para capear el problema del SPAM en nuestros blogs.

El sistema

antispam3
(Ver Imagen)

El sistema, se basa en pensar de forma dual a la hora de implementar el formulario de comentarios de tu blog (que apartir de este momento, va a ser WordPress), y barajar la idea de que un robot pueda rellenar los campos automáticamente haciendo que sus comentarios entraran como un comentario normal. Akismet, y demás plugins antispam, tienen una gran lista de URL’s, agentes de usuarios, emails e IP’s que comprueban para comprobar que un robot es malicioso o no, pero estos sistemas, como ya bien sabemos, no son del todo eficaces. Por eso, hemos de engañar al robot :D

¿Como lo engañamos?

La propuesta de Manz, es la de añadir un campo oculto (mediante CSS) con el nombre del elemento destinado para el nombre del usuario, en el caso de WordPress usaremos author, con un valor X predefinido.

<input type="text" name="author" value="X" class="oculto" />
// CSS
input.oculto {display:none;}

Este campo, será el señuelo que los robots editarán automáticamente al procesar la página, principalmente por que es un <input /> y además se llama author, lo que hace complicado saber si esa página lo tiene implementado o es una trampa.

Para los usuarios, incluiremos un nuevo elemento <input /> con un nombre a nuestra elección.

<input name="nombrebueno" type="text" class="author" />

El usuario, verá este campo y será en el que introducirá su nombre de usuario. A simple vista podemos ver el problema que nos encontramos al realizar este cambio, el nombre del usuario siempre será X, ya que WordPress está preparado para leer author como nombre de usuario, y evidentemente no conoce el campo nombrebueno que hemos creado nosotros.

Por este motivo hemos de modificar el código de WordPress para añadir unas pocas líneas (voy a explicar como lo tenía yo antes de implementar la funcionalidad que veremos abajo):

wp-config.php
define("SPAM_CONTROL", "kaminitos"); // No sé por que puse eso...
wp-comment-post.php
$comment_author       = ( isset($_POST['author']) )  ? trim(strip_tags($_POST['author'])) : null;
$comment_author_email = ( isset($_POST['email']) )   ? trim($_POST['email']) : null;
$comment_author_url   = ( isset($_POST['url']) )     ? trim($_POST['url']) : null;
$comment_content      = ( isset($_POST['comment']) ) ? trim($_POST['comment']) : null;

// Añadimos el control del campo nuevo
if ($_POST["author"] != SPAM_CONTROL) die("SPAM");
$comment_author       = ( isset($_POST['secure']) )  ? trim(strip_tags($_POST['secure'])) : null;

Se puede hacer más sencillo, editando únicamente el fichero wp-comment-post.php, pero de esta forma tengo control sobre lo que aparece en el campo oculto.

Evidentemente, este sistema, me obliga a añadir esas dos líneas de código cada vez que actualizo WordPress, lo que se convierte en algo, que aunque no es laborioso, es muy pesado. Para evitar tener que modificar el código de WordPress en cada actualización, yo propongo este código.

Sistema antispam de campo oculto más cómodo :D

// Mensaje que mostramos a los SPAM
define('MESSAGE', 'SPAM!!!');
// Nombre del campo que usaremos para alojar el verdadero nombre del usuario
define('NOMBRE_CAMPO', 'secure');
// Clave única que será modificada por el bot
define('WP_ANTI_SPAM', 'kko');

add_filter('pre_comment_author_name', '_pre_comment_author_name');
function _pre_comment_author_name($comment_author_name = ''){
 // Devolvemos el nombre del autor sinó estamos pasando los campos necesarios
 if (!isset($_POST['author'], $_POST[NOMBRE_CAMPO])) return $comment_author_name;

 // Matamos el proceso
 if (isset($_POST['author']) && $_POST['author'] != WP_ANTI_SPAM) die(MESSAGE);

 // Cambiamos el nombre del author
 global $wpdb;
 return $wpdb->escape(trim(strip_tags($_POST[NOMBRE_CAMPO])));
}

function get_anti_spam_input($comment_author){
 return '<input type="hidden" name="'.NOMBRE_CAMPO.'" value="'.esc_attr($comment_author).'" />';
}

function anti_spam_input($comment_author){
 echo get_anti_spam_input($comment_author);
}

function get_author_input($comment_author){
 return '<input type="hidden" name="author" value="'.WP_ANTI_SPAM.'" />';
}

function author_input($comment_author){
 echo get_author_input($comment_author);
}

Este código, lo incluimos en el fichero functions.php de nuestro theme. Como vemos en la parte superior, tenemos 3 define() que nos permiten declarar 3 variablesconstantes que nos hará nuestro sistema más personalizable. Después, vemos una función que se aplica al filtro pre_comment_author_name en la que comprobamos que el campo oculto no ha sido modificado. En caso de detectar el cambio, matamos el proceso en ese mismo momento, mostrando el mensaje que hayamos definido previamente.

En caso de que el campo oculto no haya sido modificado, entonces reemplazaremos el nombre de usuario por el del campo visible para el usuario. Este sistema nos permite intercalar este proceso y hacer que en caso comentario válido, continúe sin ningún problema.

Modificar el theme

Después para facilitar el trabajo de modificación del theme, he añadido unos métodos para pintar (o devolver como cadena) los elementos <input /> que intervienen en este sistema. Usaremos, como siempre, el theme default de WordPress, y usaremos únicamente el fichero comment.php del mismo.

Básicamente, el único cambio que tendremos que realizar es el cambio de esta línea:

<input type="text" name="author" id="author" value="<?php echo esc_attr($comment_author); ?>" size="22" tabindex="1" <?php if ($req) echo "aria-required='true'"; ?> />

Por estas dos

<?php
 author_input($comment_author);
 anti_spam_input($comment_author);
?>

Estos dos funciones se encargarán de pintar los elementos <input /> que vamos a necesitar. Evidentemente, si tu theme tiene estilos o clases aplicados a estos elemento tendrás que modificarlos en las funciones get_anti_spam_input() get_author_input() del fichero functions.php que hemos incluido antes.

Sencillo, ¿verdad? :D

Resultado

El resultado, os puedo garántizar que es 100% satisfactorio y que junto a Akismet el SPAM (por el momento) deja de ser un problema.