Share |

lunedì 30 maggio 2011

HTML5: test del supporto di Canvas

In questo breve articolo HTML5 sarà mostrato come verificare tramite Javascript il supporto di qualunque browser ai nuovi componenti Canvas e CanvasText.

Introduzione a Canvas

Canvas è un'area, o un riquadro, all'interno di una pagina HTML5 nel quale è possibile disegnare figure, cerchi, linee e testi ma solo utilizzando javascript.
Di per se l'elemento canvas non fa niente e non serve a niente.

Poichè HTML5 non è ancora uno standard, è altamente consigliato testare l'esistenza di questo oggetto ( e non dell'elemento HTML) anziché darla per scontata.

Di seguito un esempio di utilizzo dell'elemento canvas in una pagina HTML5.

<!DOCTYPE html>

<html lang="it">
<head>
  <meta charset="utf-8" />
  <title>Script e articoli informatici</title>
  <meta name="author" content="Mirko Agrati" />
</head>
<body>
  <canvas id="nuovoCanvas" width="300" height="300" 
      style="border: 1px solid black"></canvas>
</body>
</html>

Testare il supporto del browser

Per verificare che un browser supporti l'oggetto Canvas è necessario, ma non sufficiente, crearne un'istanza con javascript.

Se effettivamente il browser offre il supporto al componente allora sarà possibile accedere alle proprietà specifiche di Canvas, altrimenti ne sarà comunque creata un'istanza nella memoria del client, ma sarà fornita di un set di proprietà standard come un qualunque elemento HTML.

Una proprietà specifica di Canvas, che sicuramente lo caratterizza, è context, accessibile tramite il metodo getContext() esposto dal componente.

Ad oggi tale metodo restituisce solo un contesto grafico 2D, ovvero bidimensionale, anche se da specifiche è già pronto per il 3D, cioè tridimensionale.

Quindi, dopo aver creato un'istanza di Canvas è opportuno testarne la proprietà context: solo se questa non è nulla allora si può essere certi che tale browser supporta l'oggetto HTML5 Canvas!

Di seguito una semplice funzione javascript per testare il supporto a Canvas.

La function hasCanvas()

/**
 * Testa il supporto all'oggetto Canvas 
 * di un browser utente.
 *
 * @return boolean 
 */
function hasCanvas(){
  return (!! document.createElement('canvas').getContext('2d'));
}

Come spiegato qui, la sintassi javascript !! è un modo per forzare una risposta di tipo booleano, ovvero true o false.

Quindi, se la chiamata alla funzione javascript hasCanvas() restituirà true allora il browser supporta il nuovo componente Canvas, altrimenti no.

Introduzione a CanvasText

Detto questo, è bene specificare che le novità di Canvas riguardo alle funzionalità relative al testo, ovvero CanvasText, sono state introdotte successivamente e ciò implica che non basta testare il supporto a Canvas per essere certi di poter utilizzare CanvasText.

Per conoscere se un browser supporta anche CanvasText è necessario, proprio come fatto per Canvas, accedere a sue proprietà e metodi specifici.

Il fattore discriminante di cui abbiamo bisogno è rappresentato dalla proprietà fillText dell'oggetto Canvas: la presenza di questa proprietà rivela se il browser utilizzato supporta le funzionalità per il trattamento di stringhe.

Quindi, dopo aver verificato l'esistenza di canvas, si procederà al test della proprietà fillText.

Di seguito un esempio.

La function hasCanvasText()

/**
 * Testa il supporto all'oggetto CanvasText
 * di un browser utente.
 *
 * @return boolean 
 */
function hasCanvasText(){
  var unCanvas = document.createElement('canvas').getContext('2d');

  if(!!unCanvas)
    return (!! unCanvas.fillText);

  return false;
}

Se la chiamata alla funzione javascript hasCanvasText() restituirà true allora il browser supporta il nuovo componente CanvasText, altrimenti no.

Alla prossima,
MA.

sabato 28 maggio 2011

HTML5 : Rendere IE8 compatibile

In questo articolo presenterò trucchi e librerie javascript per migliorare il supporto che il browser Internet Explorer 8 offre delle specifiche HTML5.

Come risaputo, e comprovato, l'unico browser di casa Microsoft a supportare le specifiche del nuovo linguaggio HTML5 é IE9.

Questo vuol dire che nativamente IE8 non conosce ne i nuovi elementi semantici ne quelli strutturali che HTML5 ha introdotto: nav, header, foooter, section, aside ecc..

Quindi, bisogna mettere in pratica qualche workaround per far si che le nuove applicazioni, o siti web, create possano essere utilizzate da browser un po' datati, proprio come IE8.

Perfezionare i fogli di stile CSS

In generale, adattare i file CSS progettati su documenti HTML5 per far si che IE8 e tutti gli altri browser, che non conoscono i nuovi tags, possano correttamente applicarne le regole non richiede molti sforzi ne modifiche: giusto qualche accorgimento in fase di progettazione.

Per ottenere ciò sono sufficenti due accorgimenti:

  1. assegnare un id ai nuovi elementi nelle pagine HTML per poterli poi referenziare all'interno dei fogli di stile CSS;
  2. All'interno delle istruzioni di stile indicare la modalità di visualizzazione dei nuovi elementi;

Di seguito un semplice esempio:

<!DOCTYPE html>
<html lang="it">
<head>
  <meta charset="utf-8" />
  <title>Script e articoli informatici</title>
  <meta name="author" content="Mirko Agrati" />
  <style type="text/css">
    header#intestazione{backgorund-color: yellow;display: block;}
    nav#menu{backgorund-color: yellow;display: block;}
    div#content article{backgorund-color: red;display: block;}
    footer#piepagina{backgorund-color: silver;display: block;}
  </style>
</head>
<body>
  <div>
    <header id="intestazione">
      <h1>HTML5 MA Page</h1>
    </header>
    <nav id="menu">
      <a href="/">Home</a>
      <a href="/contact">Contact</a>
    </nav>
    <div id="contenuto">
         <article>
           ..........
         </article>
    </div>
    <footer id="piepagina">
     <p>© Copyright 2011 by Mirko Agrati</p>
    </footer>
  </div>
</body>
</html>

Avrai sicuramente notato che gli stili CSS dei nuovi tags referenziano gli elementi stessi tramite id ed indicano esplicitamente in che maniera disporli nella pagina tramite l'istruzione display:block;.

Questi semplici accorgimenti permettono la corretta visualizzazione di un documento HTML5 su tutti i browser, ad eccezione di IE8: per via del DOM molto selettivo,poco flessibile e non sapendo dell'esistenza dei nuovi tags, quest'ultimo browser non applica le regole di stile agli elementi sconosciuti, vanificando tutto quello di cui sopra.

Fortunatamente esiste un workaround javascript per risolvere anche questo inconveniete!

Estendere il DOM tramite Javascript

Grazie ad un tip, o trucco, javascript è possibile imporre la conoscenza dei nuovi tags HTML5 ad Internet Explorer 8 il quale, non appena appresa la notizia, provvederà ad applicare le regole CSS ai nuovi elementi annullando l'handicap nei confronti degli altri browser.

Nell'esempio che segue, verranno creati i nuovi elementi al caricamento della pagina, in maniera tale che il DOM li abbia già a disposizione prima di dover assegnare loro gli stili CSS.

Il codice seguente va ad integrare la sezione HEAD dell'esempio precedente.

<head>
  ........

  <script type="text/javascript">
    document.createElement('header');
    document.createElement('nav');
    document.createElement('article');
    document.createElement('footer');
  </script>

</head>

Per evitare ogni volta di dover creare tutti gli elementi HTML5 che IE8 non conosce, è possibile crearsi uno script personale oppure utilizzarne uno già pronto creato da Remy Sharp e distribuito gratuitamente sul suo blog a questo indirizzo.

Il file javascript html5.js, scaricabile e direttamente linkabile da ogni pagina HTML, é da inserire nella sezione HEAD del documento e per assicurasi che venga caricato solo in presenza di un client IE8 va trattato nella maniera che segue.

<head>
  ........
  <!--[if lt IE 9]>
    <script src="http://html5shim.googlecode.com/svn/trunk/html5.js">
    </script>
  <![endif]-->

</head>

Ovviamente il suddetto file .js è distribuito in versione minified, ovvero ridotta al minimo per essere scaricata velocemente.

Alla prossima,
MA.

giovedì 26 maggio 2011

HTML5: Test della proprietà geolocation

Tra le tante novità introdotte da HTML5 una delle più importanti è la geolocalizzazione.

Attraverso l'analisi della provenienza di una connessione di rete, piuttosto che del segnale GPS di un dispositivo mobile, questa funzionalità permette di localizzare la posizione di un client utente.

Ovviamente, non essendo ancora HTML5 uno standard, non è possibile dare per scontato che tutti i browsers supportino la funzionalità di geolocalizzazione.

In questo breve articolo, mostrerò un piccolo javascript utile per verificare che un qualsiasi browser supporti la proprietà geolocation, in modo da poterne eventualmente gestire la mancanza senza pregiudicare il corretto funzionamento dell'applicazione.

Un browser supporta la geolocalizzazione se e solo se l'oggetto navigator espone la proprietà geolocation.

Di seguito il codice sorgente del javascript.

La function hasGeolocation()

/**
 * Testa il supporto alla funzionalità di geolocalizzazione 
 * di un browser utente.
 *
 * @return boolean 
 */
function hasGeolocation(){
  return (!!navigator.geolocation);
}

Certamente nulla di strano ne di complesso!

L'unica eccezione, che potrebbe sembrare un errore, è la presenza di 2 punti esclamativi consecutivi: la sintassi javascript !! è un modo per forzare una risposta di tipo booleano, ovvero true o false.

Se la chiamata alla funzione hasGeolocation() dovesse restituire un false allora si dovrà gestire la mancanza della possibilità di localizzare una connessione. Di seguito un esempio.

<script type="text/javascript">
........

if(! hasGeolocation()){
  alert('Questo browser non supporta la Geolocalizzazione.');
  return -1;
}

........
</script>

Alla prossima,
MA

venerdì 20 maggio 2011

JSP 2.0 : Internazionalizzare web applications

Oggi presento un custom tag java che permette facilmente di internazionalizzare il testo contenuto in qualunque JSP sviluppata con tecnologia JSP2.0 .

Il custom tag Dictionary è molto semplice, questo perchè la logica che sta alla base del funzionamento è incapsulata dalla classe di business Translator.

Il codice sorgente, il funzionamento e le caratteristiche della classe Translator sono state già affrontate ed ampiamente spiegate in questo precedente articolo.

Se hai bisogno di ripassare brevemente l'argomento custom tags puoi fare riferimento invece a questo link.

Il tag Dictionary

Visto che la logica per la traduzione e la cache dei vocaboli traducibili sono mutuati alla classe Translator, a questo componente rimane esclusivamente l'onere di carpire la lingua dell'utente che naviga nell'applicazione.

Per fare questo, basta estrarre il giusto header che qualunque browser invia nella head di ogni sua richiesta: nel caso particolare, il componente estrae dalla collection di informazioni, o headers, quella abbinata alla chiave "accept-language".

In questo articolo, è dato per scontato che vi sia una sola lingua utente (es: it per italiano), anche se in realtà è possibile che sia restituito un elenco di lingue separate da virgola (es: en, us).

Il tag ha solo un attributo chiamato name che è anche obbligatorio, di seguito la sua dichiarazione all'interno del Tag Library Descriptor file

<?xml version="1.0" encoding="UTF-8"?>
 
<!DOCTYPE taglib PUBLIC "-//Sun Microsystems, 
      Inc.//DTD JSP Tag Library 1.2//EN"
      "http://java.sun.com/j2ee/dtd/web-jsptaglibrary_1_2.dtd">
 
<taglib>
  <tlib-version>1.0</tlib-version>
  <jsp-version>2.0</jsp-version>
  <short-name>ma</short-name>
  <uri>http://java.ma.it/jsp/jstl/ma</uri>
  <display-name>MA Tags Library</display-name>
  <description>Mirko Agrati's Tags Library</description>
 
  <tag>
    <name>dictionary</name>
    <tag-class>net.ma.java.tag.Dictionary</tag-class>
    <body-content>empty</body-content>
    <description>
      Provvede alla traduzione di etichette e brevi testi.
    </description>
 
    <attribute>
      <name>name</name>
      <required>true</required>
      <rtexprvalue>true</rtexprvalue>
    </attribute>
  </tag>
 
</taglib>

Rimane ora da analizzare il codice sorgente del componente.

package net.ma.java.tag;
/**
 * Provvede alla traduzione di etichette e brevi testi.
 * 
 * @author  Mirko Agrati
 * @version 02/mag/2011 - v1.1
 */
public final class Dictionary extends SimpleTagSupport {

  private String name;
 
  public Dictionary(){
    super();
    name = null;
  }
 
  @Override
  public void doTag() throws JspException, IOException {
    pageContext = (PageContext)getJspContext();

    try{
      String extraInfo = pageContext.getPage().getClass().getName();
      HttpServletRequest req = (HttpServletRequest)pageContext.getRequest();
      String language = req.getHeader("accept-language"); 
      String translated = Translator.translate(language, name, extraInfo);

      pageContext.getOut().write(translated);
    }
    catch ( Exception e ) {
      throw new JspException(e);
    }
  }

  public void setName(String n){
    name = n;
  }
}

Come avrai notato, il cuore del tag è l'estrazione del header con chiave accept-language , che contiene la lingua con cui è impostato il browser utente, e la chiamata al metodo translate , al quale si passa la lingua, il termine da tradurre ed eventuali note per tracciare richieste particolari.
Il termine tradotto viene infine scritto nel corpo della JSP.

Di seguito un esempio di utilizzo del tag Dictionary.

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN">
<%@page language="java" pageEncoding="UTF-8"
      contentType="text/html; charset=UTF-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<%@ taglib uri="http://java.ma.it/jsp/jstl/ma" prefix="ma" %>
<HTML>
<HEAD>
  <META http-equiv="Content-Type" content="text/html; charset=UTF-8">
  <meta http-equiv="Content-Style-Type" content="text/css">
  <meta http-equiv="Cache-Control" content="no-cache">
  <meta http-equiv="Pragma" content="no-cache">
  <title>Custom tag Dictionary</title>
</HEAD>
<BODY>
  <ma:dictionary name="Ciao" />
</BODY>
</HTML>

Il tutto risulta essere molto semplice e flessibile, potenzialmente utilissimo in tutte le java web app.

Alla prossima,
MA