Els vídeos de la Google IO 2012

Aquesta setmana que tot just acaba ha vist una nova edició de la conferència Google IO d’enguany, al Moscone Center de San Francisco.

A la web de la Google IO 2012 ja han penjat molta informació útil.Per fer-se una idea general de la conferència, poden ser útils els vídeos de les sessions d’apertura (keynotes) dels dos primers dies.

Keynote Day 1

Keynote Day 2

La veritat és que l’ambient és fabulós. Fan venir ganes de ser-hi allà.

S’han presentat els nous productes i projectes de Google.

Per exemple, les Google Glasses

I la nova tablet Google Nexus 7 amb Android 4.1 Jelly Bean

També trobarem vídeos de les sessions tècniques. N’hi han un munt. Per exemple:

Novetats per a desenvolupadors Android:

Acrobàcies amb HTML5

SDK per a integrar aplicacions amb el Google Drive

Aplicacions HTML5 amb Google Chrome

Podeu trobar molts més vídeos de la Google IO al YouTube, al canal GoogleDevelopers, i a la mateixa web de Google Developers.

Algun any d’aquests caldrà fer un pensament i anar a veure què es cou a la Google IO.

Les presentacions de DeSymfony 2012

Fa tot just una setmana es va clausurar a Castelló la deSymfony 2012.

Symfony és un framework per a desenvolupar aplicacions web amb PHP. La conferència DeSymfony, amb el patrocini de la Universitat Jaume I, és un punt de referència imprescindible per als desenvolupadors que utilitzen aquesta eina.

Durant dos dies es van fer tot un seguit de presentacions que van tractar diferents aspectes del desenvolupament amb Symfony. A la web de Symfony.es han penjat les presentacions (els ppt, per entendre’ns). Properament penjaran els vídeos. Estarem atents.

Enganxo aquí els enllaços a les presentacions:

 

Divendres, 15 de juny

Dissabte, 16 de juny

Apunts d’HTML5

HTML5 és més que un llenguatge d’etiquetes. És el resultat de la convergència dels esforços del WWW Consortium i el WHATWG per a fer evolucionar l’HTML. Amb HTML5 podem parlar pròpiament de “programació”. A la vegada, es manté la compatibilitat cap enrere, Tot HTML previ a HTML5 “és també” HTML5. Ara bé, si fem servir les noves etiquetes, fulls d’estil i les noves APIs de javascript podrem arribar molt lluny.

Una demostració del que es pot arribar a fer amb HTML5 és aquest Mario Bros. El codi es pot descarregar. Només cal registrar-se gratuitament a codeproject.com.

Què ens proporciona HTML5? Sense ser exhaustius:

– Noves etiquetes amb nova semàntica per a organitzar millor la presentació de la informació
– Noves etiquetes per a afegir àudio i vídeo a les pàgines sense haver de dependre de plugins de terceres parts.
– Canvas, que ens permet dibuixar en 2D i 3D generant imatges tipus bitmap.
– SVG Scalable Vector Graphics. Per a generar imatges vectorials.
– Un mecanisme nou i consistent entre els diferents browsers per a emmagatzemar dades locals (Local Storage, més enllà de les cookies).
– Nous tipus de camps als formularis HTML amb, això és important, validació pel propi navegador.
– Geolocalització.
– Microdata (una eina per al posicionament a Internet).
– aplicacions offline.
– Base de dades SQL local
– …

Compatibilitat
HTML5 no està especificat del tot. No tots els navegadors dels diferents dispositius suporten HTML5, només els més moderns. No tots els navegadors moderns suporten “tot” l’HTML5. O el suporten exactament igual. En definitiva, res de nou.

Tanmateix, és una bona idea avançar poc a poc en la migració a HTML5. Tot l’HTML anterior a HTML5 és, també HTML5, per tant, la transició a HTML5 “heavy” es pot encetar gradualment.

Abans d’utilitzar una característica d’HTML5 caldrà determinar si està disponible al navegador de l’usuari. En entorns controlats, com intranets, on el navegador de l’usuari pot estar especificat, aquesta pot ser una tasca senzilla. En entorns més oberts una aproximació útil és fer servir llibreries javascript per a determinar les prestacions del navegador. Una de recomanada sovint als diferents manuals és la llibreria opensource Modernizr.

En general, fent servir Modernizr, seguirem el següent esquema:

if (Modernizr.CaracterísticaHTML5) {
    // puc fer servir HTML5
} else {
    // no puc fer servir HTML5
}

Anem a repassar amb més detall algunes opcions:

Noves etiquetes (algunes)
Noves etiquetes per a organitzar la informació, section, article… N’hi han moltes més!

<section>
una secció
<aside> 
informació addicional
</aside>
<header>la capcelera</header>
<article>un article</article>
<footer>el peu</footer>
</section>

Aquestes etiquetes permeten organitzar la informació de forma més propera a com s’està presentant habitualment. Un dels criteri en el desenvolupament d’HTML5 és “estandaritzar” allò que s’està fent. O si es vol, de regular les bones pràctiques. És dir, no s’inventa res si no cal, més aviat, s’afina. Les etiquetes section, article… anteriors es podien trobar abans d’HTML5 com els noms més habituals en DIVs, com va descobrir Google en analitzar milers de pàgines, fent les funcions d’organització que justament ara assumeixen.

CSS
Aquestes etiquetes no tenen, a priori, una representació gràfica predeterminada i això ens porta a l’altre element fonamental de’HTML5: el CSS3 (CSS level 3, acrtualment en desenvolupament).

A HTML5 es considera una mala pràctica (en realitat, des d’abans d’HTML5 que es considera una mala pràctica) l’ús dels atributs modificadors de la presentació a les etiquetes. Totes les característiques de presentació haurien d’anar a fulls d’estil CSS.

Etiquetes per a audio i video
Finalment, l’audio i el video es podran reproduir de forma nativa sense que calguin plugins (és la fi de Flash?). En realitat, la reproducció d’àudio i vídeo nativa dependrà dels còdecs disponibles. A més, no tots els navegadors suporten les etiquetes audio i video. Tot plegat, la següent estructura es pot utilitzar com a punt de partida:

Audio:

<audio controls>
    <source src="audio.ogg" type="audio/ogg">
    <source src="audio.mp3" type="audio/mpeg">
    <a href="http://player.swf?soundFile=audio.mp3">
    http://player.swf?soundFile=audio.mp3</a>
</audio>

L’explicació és la següent: la llista de sources ens permet proporcionar l’audio en diferents formats, amb l’esperança que algun d’ells serà nadiu al navegador dels usuaris (ogg és nadiu a firefox i chrome). El navegador reproduirà el primer de la llista per al que disposi de còdecs. Atenció, doncs, a l’ordre! En cas que el navegador no suporti l’etiqueta audio, aleshores, encara es podrà fer servir el plugin de flash. Si tampoc això funciona, es podrà descarregar el fitxer d’àudio amb un enllaç.

Vídeo:
És simètric a l’anterior:

<video controls 
width="360" height="240"
       poster="poster.jpg">
    <source src="video.ogv" type="video/ogg">
    <source src="video.mp4" type="video/mp4">
    <a href="http://player.swf?file=video.mp4">
    http://player.swf?file=video.mp4</a>
</video>

Com a comentari general, vàlid per a audio i video, indicar que cal especificar correctament els Content-type dels àudios i els vídeos. No A més, cal que els Content-types estiguin disponibles a la llista de Content-types del servidor web que serveis les pàgines.

Canvas
Canvas ens permet dibuixar. Això que sembla tan poca cosa, senzillament no es podia fer abans de forma fàcil. Ara es pot. l’etiqueta canvas determina una regió rectangular en la que es podrà, mitjançant javascript, dibuixar línies, rectangles, corbes… pintar de colors, amb diferents tipus de pinzells, aplicar transformacions…
Canvas és, en ell mateix, tot un món. Vegem-ne un petit exemple:

<!DOCTYPE html>
<html>
<head><title>Canvas</title>
<script>
function Pinta() {
    alert(Math.PI);
    var canvas = document.getElementById('idCanvas');
    var ctx = canvas.getContext('2d');
    ctx.beginPath();
    ctx.moveTo(10,120);

    for(var x=10; x<=310; ++x) {
        y = 100*Math.sin(2*Math.PI*(x - 10)/300);
        ctx.lineTo(x, 120 - y);
    }
    ctx.stroke();
}
</script>
</head>
<body onload="Pinta()">

<canvas id="idCanvas" width="320" height="240">
</canvas>
</body>
</html>

Ens dibuixa la bonica corba sinusoïdal.

 

SVG
No només es poden crear programàticament imatges bitmap o raster. Tambés es poden crear imatges vectorials amb SVG. SVG ja és un vell conegut de diferents browser, com el Firefox, però ara passa a formar part de “l’especificació” d’HTML5. Per a il·lustrar, aquí mostro el que podria ser l’esquelet d’un petit joc:  proveu a fer click al cercle roig que batega i es mou ràpidament per la regió rectangular. Vet aquí una combinació de SVG i JavaScript.

Aquesta animació ha estat del tipus programàtic basada en setInterval de JavaScript, però és possible animar els objecte SVG de forma declarativa, amb l’element “animate”.

<!DOCTYPE html>
<html>
<head>
<meta charset="latin-1" />
<title>svg</title>
<script>
var xx=240;
var yy=160;
var rr=10;
var ix=1; var iy=1; var ir=1;
var obj=null;
var objClicks = null;
var totalClicks = 0;
function init() {
  obj = document.getElementById("idCercle");
  objClicks = document.getElementById("idScoring");
  setInterval("anima()",10);
}

function anima() {
  obj.setAttribute("cx", xx);
  obj.setAttribute("cy", yy);
  obj.setAttribute("r",rr);

  xx += ix; yy += iy; rr += ir;

  if (((xx + rr) > 480) || ((xx - rr) < 0)) {ix = -ix};
  if (((yy + rr) > 320) || ((yy - rr) < 0)) {iy = -iy};
  if ((rr > 20) || (rr < 5)) {ir = -ir};

  return true;
}

function ImA(whatiam) {
      ++totalClicks;
	  objClicks.innerHTML="jo soc un " + whatiam + "; total de clicks: " + totalClicks;
	  return true;
}
</script>
</head>
<body onload="init()">
<svg height="320" width="480" id="idSvgCanvas">
    <circle fill="#ff0000" onclick="ImA('cercle');" id="idCercle">
	</circle>
</svg>
<div id="idScoring">Click me!</div>
</body>
</html>

 

Nous tipus de camps de formulari

HTML5 afegeix nous camps de formulari. Pel que fa a la compatibilitat amb navegadors no HTML5, aquests representaran als nous camps com camps de text. De fet, aquest serà el comportament dels navegadors que suporten HTML5 però que no tenen un comportament específics per a aquests nous tipus.

Dit d’una altra forma, si preveiem que un camp d’un formulari s’adapta a algun dels nous tipus, és interessant fer servir el nou tipus, encara que el navegador no suporti HTML5 perquè, de totes formes, els seguirà presentant com una caixa de text.
En un futur aquests nous camps estaran.

Actualment ja hi han alguns navegadors que fan un tractament especial i validació “nadiua” per a determinats camps.

En el cas de Google Chrome, de moment hi ha representació gràfica especial per als type=”number”, type=”range” i s’ha afegit l’atribut “placeholder” en els input type de tipus text.

<!DOCTYPE html>
<html>
<head><title>Form</title>
</head>
<body ">
<form id="idForm">
data: <input type="date" name="data" placeholder="data"/><br />
hora: <input type="time" name="hora" placeholder="hora"/><br />
placeholder: <input type="text" placeholder="prova placeholder" name="texts" /><br />
email: <input type="email" name="email" placeholder="email" /><br />
url: <input type="url" name="url" placeholder="url"/><br />
Nombre: <input type="number" min="0" max="100" step="5" value="50" /><br />
Rang: <input type="range" min="0" max="100" step="5" value="50" /><br />
cerca: <input type="search" name="cerca" placeholder="cerca"><br />
color: <input type="color" name="color" placeholder="color"><br />
</form>
</body>
</html>

El codi anterior es presenta de la següent forma amb Google Chrome:

Geolocalització
Si està disponible en el navegador del dispositiu mòbil de l’usuari la geolocalització, geolocation, permet, si l’usuari dona el seu permís, que els llocs puguin conèixer l’ubicació del dispositiu del client. Depenent del dispositiu aquesta ubicació es determina de forma molt precisa, via gps, o no tant, per triangulació entre repetidors de telefonia, o de forma més burda, per rang d’IP del proveïdor. A priori, doncs hi ha indeterminació pel que fa a la precisió en la geolocalització, i en el temps de resposta. És més costosa, però molt més precisa, una localització per GPS que una localització per IP, que és immediata, però que pot tenir una “precisió” d’un radi de centenars de quilòmetres.

Un exemple de localització el tenim en el següent codi:

<!DOCTYPE html>
<html>
<head>
<meta charset="latin-1" />
<title>geoloc</title>
<script type="text/javascript">
function geoloc() {
	if (navigator.geolocation) {
	  var timeoutVal = 10 * 1000 * 1000;
	  navigator.geolocation.getCurrentPosition(
	    displayPosition, 
	    displayError,
	    { enableHighAccuracy: true, timeout: timeoutVal, maximumAge: 0 }
	  );
	}
	else {
	  alert("Aquest navegador no suporta la geolocalització");
	}
}

function displayPosition(position) {
  var lLat = position.coords.latitude; 
  var lLong = position.coords.longitude
  var sText= "<b>Latitud:</b> " + lLat + 
             ", <b>Longitud:</b> " + lLong;
  document.getElementById("idPos").innerHTML = sText;
  var sImgSrc = "http://maps.google.com/maps/api/staticmap?" +
               "center=" + lLat + "," + lLong + "&zoom=14&size=512x512&maptype=roadmap&" + 
               "markers=color:blue%7Clabel:S%7C" + lLat + "," + lLong + "&sensor=false";
  document.getElementById("idImg").src = sImgSrc;
}

function displayError(error) {
  var errors = { 
    1: 'Permission denied',
    2: 'Position unavailable',
    3: 'Request timeout'
  };
  document.getElementById("idPos").innerHTML = "Error: " + errors[error.code];
}
</script>
</head>
<body onload="geoloc()" onunload="GUnload()">
Geolocalització.<br />
<div id="idPos">Calculant posició...</div>
<img id="idImg" src="" height="512" width="512" "alt="la meva ubicació"/>
</body>
</html>

Al provar la pàgina anterior al Mozilla Firefox, primer de tot observo que em demana permís:

Li en dono, i em mostra la meva posició.

Val a dir que no ha estat gens precís! Estic fent aquest experiment amb l’ordinador de sobretaula i, evidentment, la localització va per rang d’IP. Encara bo que ha trobat que és Barcelona! Evidentment, la potència de la geolocalització apareix quan la fem servir sobre dispositius mòbils que permeten una ubicació precisa.

Microdata
Les microdata permet afegir semàntica a les pàgines html. Això que sona molt críptic, i que segurament ho és X)), es pot traduir a “un sistema per afegir informació útil a la nostra pàgina web per a que cercadors i indexadors, o sigui Google, la trobin més interessant i la facin sortir més amunt o més destacada en les cerques”.

Microdata afegeix la semàntica mitjançant uns atributs (itemscope, itemtype, itemid, itemprop, itemref) en les etiquetes de l’HTML.

Aquests atributs permeten identificar peces del contingut de la pàgina marcat per etiquetes HTML com valors de propietats definides en un vocabulari.

Els vocabularis són petits i estan relacionats amb un camp semàntic.

Les Microdata utilitzen vocabularis per a definir la semàntica que es volo afegir. Tothom pot crear els vocabularis que vulgui per al camp semàntic que li interessi, però ja n’hi han de fets. I els podeu examinar a http://www.data-vocabulary.org/

Per exemple, per al camp semàntic “persona” podem trobar el següent vocabulari a http://www.data-vocabulary.org/Person/

Property          Description
--------          ----------- 
name (fn)         Name
nickname          Nickname
photo             An image link
title             The person's title (for example, Financial Manager)
role              The person's role (for example, Accountant)
url               Link to a web page, such as the person's home page
                  affiliation (org) The name of an organization with
                  which the person is associated (for example, an
                  employer). If fn and org have the exact same value,
                  Google will interpret the information as referring
                  to a business or organization, not a person.
friend	          Identifies a social relationship between the person
                  described and another person.
contact	          Identifies a social relationship between the person
                  described and another person.
acquaintance	  Identifies a social relationship between the person
                  described and another person.
address (adr)	  The location of the person. Can have the
                  subproperties 
                       street-address, 
                       locality, 
                       region, 
                       postal-code, 
                       and country-name.

Com funciona? el següent exemple esta extret de la Wikipedia

HTML original

<section> Hello, my name is John Doe, 
I am a graduate research assistant at 
the University of Dreams. 

My friends call me Johnny. 
You can visit my homepage at 
<a href="http://www.JohnnyD.com">www.JohnnyD.com</a>. 
I live at 1234 Peach Drive Warner Robins, Georgia.
</section>

Aquest HTML se li pot afegir semàntica, és dir, significat per als cercadors, de la següent forma:

<section itemscope itemtype="http://data-vocabulary.org/Person"> 
        Hello, my name is 
        <span itemprop="name">John Doe</span>, 
        I am a 
        <span itemprop="title">graduate research assistant</span> 
        at the 
        <span itemprop="affiliation">University of Dreams</span>. 
        My friends call me 
        <span itemprop="nickname">Johnny</span>. 
        You can visit my homepage at 
        <a href="http://www.JohnnyD.com" itemprop="url">www.JohnnyD.com</a>. 
        <section itemprop="address" itemscope itemtype="http://data-vocabulary.org/Address">
                I live at 
                <span itemprop="street-address">1234 Peach Drive</span> 
                <span itemprop="locality">Warner Robins</span>
                , 
                <span itemprop="region">Georgia</span>.
        </section>
</section>

Aquest tros de codi HTML5 (noteu l’us de l’etiqueta section) és interpretat per Google de la següent forma (es pot provar el resultats d’afegir Microdata a les pàgines amb el Google’s Rich Snippet Testing Tool.)

I una advertència: que Google pugui interpretar la Microdata NO vol dir, repeteixo, NO vol dir, que forçosament en millori el posicionament.

Database Storage
L’especificació del “Database storage” permet afegir una base de dades SQL local al navegador de l’usuari, per a utilitzar-la localment i com a magatzem persistent.
L’especificació no diu quina BD ha de ser, però almenys Chrome (també Chromium i Android) i Opera estan implementant SQLite i són les úniques implementacions a dia d’avui.

La tria d’SQLite no és casual. Aquesta eficient i potent BD opensource forma part de projectes com FireFox i Chrome des de fa molt de temps. La meva opinió és que disposar d’aquesta BD formant part del nucli del navegador i no posar-la a disposició del usuari era una provocació.

Que la BD triada a les implementacions disponibles sigui SQLlite permet entre d’altres coses, que la puguem examinar (i operar amb ella) fent us d’eines com SQLIteman. Això sí, cal saber on buscar: En el cas del Linux Ubuntu 12.04 que tinc instal·lat i amb el que faig els meus experiments, resulta que, per a Chrome, les bases de dades SQLite es troben, ben amagades, a /home/usuari/.config/google-chrome/Default/databases/file__0 i es van numerant. Amb una inspecció de la carpeta no es poden identificar per nom.

Cal repetir, però, que Database Storage no està present a tots els navegadors que suporten HTML5.

Tanmateix, és temptador disposar d’una BD SQL local.

El següent és un exemple d’agenda de telefons que vaig trobar a Internet (lamentablement, no em vaig guardar l’enllaç) i que he adaptat.

<!DOCTYPE html>
<html>
    <head>
        <meta charset="latin-1" />
        <title>SQL Storage</title>
            
        <script>        
        var sCreate = "CREATE TABLE IF NOT EXISTS Agenda (id INTEGER PRIMARY KEY AUTOINCREMENT, Nom TEXT, cognom TEXT, telefon TEXT)";
        var sSelectAll = "SELECT * FROM Agenda";
        var sInsert = "INSERT INTO Agenda (Nom, cognom, telefon) VALUES (?, ?, ?)";
        var sUpdate = "UPDATE Agenda SET Nom = ?, cognom = ?, telefon = ? WHERE id = ?";
        var sDelete = "DELETE FROM Agenda WHERE id=?";
        var sDrop = "DROP TABLE Agenda";
        var db, dataset;        
        var resultats, id, Nom, cognom, telefon;
        
        function inicialitza() {
            resultats = document.getElementById('resultats');
            id = document.getElementById('id');
            Nom = document.getElementById('Nom');     
            cognom = document.getElementById('cognom'); 
            telefon = document.getElementById('telefon');
            db = openDatabase("AgendaTelefons.db", "1.0", "Agenda de Telefons", 200000);
            crearTaula();
        }
        
        function onError(tx, error) {
            alert(error.message);
        }
        
        function mostrarFiles() {
            resultats.innerHTML = '';
            db.transaction(function(tx) {
                tx.executeSql(sSelectAll, [], function(tx, result) {
                    dataset = result.rows;
                    for (var i = 0, item = null; i < dataset.length; i++) {
                        item = dataset.item(i);
                        resultats.innerHTML +=
                        '<li>' + item['cognom'] + ' , ' + item['Nom'] + 
                        ' <a href="#" onclick="carregarFila('+i+')">modificar</a>  ' + 
                        '<a href="#" onclick="esborrarFila('+item['id']+')">esborrar</a></li>';
                    }
                });
            });
        }
        
        function crearTaula() {
            db.transaction(function(tx) {
                tx.executeSql(sCreate, [], mostrarFiles, onError);
            });
        }
        
        function afegirFila() {
            db.transaction(function(tx) {
                tx.executeSql(sInsert, [Nom.value, cognom.value, telefon.value], carregar_i_reset, onError);
            });
        }
        
        function carregarFila(i) {
            var item = dataset.item(i);
            Nom.value = item['Nom'];
            cognom.value = item['cognom'];
            telefon.value = item['telefon'];
            id.value = item['id'];
        }
        
        function actualitzarFila() {
            db.transaction(function(tx) {
                tx.executeSql(sUpdate, 
                          [Nom.value, cognom.value, telefon.value, id.value], 
                          carregar_i_reset, 
                          onError);
            });
        }
        
        function esborrarFila(id) {
            db.transaction(function(tx) {
                tx.executeSql(sDelete, [id], mostrarFiles, onError);
            });
            netejaFormulari();
        }
        
        function esborrarTaula() {
            db.transaction(function(tx) {
                tx.executeSql(sDrop, [], mostrarFiles, onError);
            });
            netejaFormulari();
        }
        
        function carregar_i_reset() {
            netejaFormulari();
            mostrarFiles();
        }
        
        function netejaFormulari() {
            Nom.value = '';
            cognom.value = '';
            telefon.value = '';
            id.value = '';
        }
        </script>
    </head>
    
    <body onload="inicialitza();">   
        <br/><br/>
        <div align="center">
            <input type="hidden" id="id"/>
            Nom:<input type="text" id="Nom"/><br/>
            Cognom:<input type="text" id="cognom"/><br/>
            Telefon: <input type="text" id="telefon"/><br/>
            <button onClick="netejaFormulari()">Neteja Formulari</button>
            <button onClick="actualitzarFila()">Actualitzar</button>
            <button onClick="afegirFila()">Afegir</button>
            <button onClick="esborrarTaula()">Esborrar taula</button>
            <div id="resultats"> </div>
        </div>
    </body>
</html>

Local Storage
Local Storage és una alternativa als Cookies. És dir, és un mecanisme senzill i consistent entre els navegadors per a emmagatzemar parelles nom-valor de forma persistent (o sigui que entre sessions mantenim la informació).

Aquesta característica l’implementen tots els navegadors que suporten HTML5, des de Internet Explorer fins a Safari, passant pels Chrome, Android, Opera o FireFox. Com a curiositat, en el cas de FireFox resulta que la tecnologia amb que s’implementa Local Storage és, ves quina cosa, SQLite.

LocalStorage proporciona una API senzilla:
getItem(clau),
setItem(clau, valor),
removeItem(clau),
lenght: número de clausdeter
key(index): clau i-èssima

Els dos últims ens permeten implementar un iterador. Anem a repetir l’agenda de telefons fent servir LocalStorage:

<!DOCTYPE html>
<html>
    <head>
        <meta charset="latin-1" />
        <title>Local Storage</title>
            
        <script>              
        var resultats, NomCognom, telefon;
        
        function inicialitza() {
            resultats = document.getElementById('resultats');
            NomCognom = document.getElementById('NomCognom');     
            telefon = document.getElementById('telefon');
            mostrarFiles();
        }
        
        
        function mostrarFiles() {
            resultats.innerHTML = '';
            for (var i = 0; i < localStorage.length; i++) {
            	item = localStorage.key(i);
               resultats.innerHTML +=
               '<li>' + item + "-" + localStorage[item] + 
               ' <a href="#" onclick="carregarFila(\''+ item +'\')">modificar</a>  ' + 
               '<a href="#" onclick="esborrarFila(\''+ item + '\')">esborrar</a></li>';
            }
        }
        
        
        function afegirFila() {
            localStorage[NomCognom.value] = telefon.value;
            mostrarFiles();            
        }
        
        
        function carregarFila(item) {
            NomCognom.value = item;
            telefon.value = localStorage[item];
        }
        
        
        function esborrarFila(item) {
            localStorage.removeItem(item);
            netejaFormulari();
        }
        
        
        function netejaFormulari() {
            NomCognom.value = '';
            telefon.value = '';
            mostrarFiles();
        }
        </script>
    </head>
    
    <body onload="inicialitza();">   
        <br/><br/>
        <div align="center">
            Nom i cognom: <input type="text" id="NomCognom"/><br/>
            Telefon: <input type="text" id="telefon"/><br/>
            <button onClick="netejaFormulari()">Neteja Formulari</button>
            <button onClick="afegirFila()">Afegir - Actualitzar</button>
            <div id="resultats"> </div>
        </div>
    </body>
</html>

I recordem que amb Chrome, podem repassar el contingut del localStorage (amb F12, eines de desenvolupador, a la pestanya resources).

Aplicacions Offline
Amb HTML5 podem fer aplicacions. Les aplicacions amb HTML5 són aplicacions web, és dir, connectades. Aplicacions que viuen a Internet. Tanmateix, característiques com Local Storage o Database Storage ens obren la possibilitat a desenvolupar aplicacions que puguin treballar desconnectades.

Les aplicacions desconnectades es descarregaran total o parcialment al nostre dispositiu, i seran funcionals quan el dispositiu no estigui connectat a Internet, és dir, físicament estaran al nostre dispositiu.

Fer una aplicació offline és tan senzill com afegir-li un fitxer de manifest de caché a una aplicació HTML5 “normal”, i que les pàgines de l’aplicació el declarin a l’etiqueta HTML

<html manifest="/cache.manifest">

El manifest té un content-type específic: “text/cache-manifest”. Cal assegurar que el servidor web serveix el content type correctament.

Què hi posarem en aquest manifest? ni més ni menys que la llista de pàgines i recursos que formaran l’aplicació offline. Un cop el navegador llegeixi el manifest procedirà a descarregar els diferents components. Per exemple:

CACHE MANIFEST
/index.html
/estils.css
/scripts.js
/imatge01.jpg
/imatge02.jpg
/imatge03.jpg

La primera línia ha de ser “CACHE MANIFEST”.

Tanmateix, també podem voler que hi hagin pàgines o recursos que explícitament no es descarreguin mai. Aleshores podem distingir entre recursos a la xarxa, i recursos a la caché

   
CACHE MANIFEST
NETWORK:
/comptador.php
CACHE:
/index.html
/estils.css
/scripts.js
/imatge01.jpg
/imatge02.jpg
/imatge03.jpg

Els recursos a la secció NETWORK no seran descarregats.

A més, por passar l’aplicació web hi hagin recursos que no estiguin definits ni a NETWORK, ni a CACHE. En aquest cas podem tenir una secció FALLBACK per a tractar aquests casos especials.

Per a saber-ne molt més
Hi han molts i molt bons manuals d’HTML5. I alguns d’ells es poden trobar lliures a Internet. En particular, jo m’he llegit, o m’estic llegint els següents:

http://diveintohtml5.info/. Aquesta web és la versió online i lliure del llibre “HTML5. Up and Running” de Mark Pilgrim, publicat per O’Reilly.

Un altre llibre interessant: Pro HTML5 Programming, publicat per Apress

Aquest és molt fàcil de llegir, és curtet i va al gra: HTML5 for Web Designers, publicat per “A Book Apart”.

Una cerca a la web us proporcionarà molts resultats. Els llibres que he citat són, simplement, alguns que he llegit i que, per tant, amb veig amb cor de recomanar.

A més, crec que és molt útil disposar des “xuletaris” o cheat sheets. Aquests estan molt bé:

HTML 5: http://webdesign.about.com/b/2012/05/01/html5-cheat-sheet.htm

Encara un altre d’HTML5: http://www.smashingmagazine.com/2009/07/06/html-5-cheat-sheet-pdf/

Canvas: http://www.nihilogic.dk/labs/canvas_sheet/

Un bon xuletari de CSS també ajuda
CSS: http://coding.smashingmagazine.com/2009/07/13/css-3-cheat-sheet-pdf/

En aquest enllaç, fins i tot fan una recopilació de cheat sheets de CSS.

Finalment, si voleu veure exemples d’HTML5 en acció,aquesta web en proporciona molts: http://html5demos.com/