Categoria ‘CSS’


Editor WYSIWYG per il Web

TynyMCE 2.1.2 (3.01 alpha)

TinyMCE Giunto alla versione 3.01a (l’ultima stabile è la 2.1.2), TinyMCE supporta i seguenti browser: browser supportati: Mozilla, MSIE, FireFox, Opera and Safari (experimental) (Mozilla, MSIE, FireFox, Opera and Safari (experimental)).
Grazie al supporto dei Plugins è completamente configurabile, sia a livello di Skin (vedi immagin in basso per due esempi) sia a livello di caratteristiche supportate (vedi Plugins). Completo di language pack permette di personalizzare l’output XHTML 1.0. Utilizzabile da PHP/.NET/JSP/Coldfusion GZip compressor supporta anche Ajax per le operaqzioni di Load/Save.

Continua...

Prototype 1.6.0 release candidate

È stata appena rilasciata la release candidate 1.6.0 di prototype con interessanti aggiornamenti all’intero sistema di API. In particolare il metodo observe dell’oggetto Event è stato migliorato e ora fornisce il contesto dell’oggetto che ha rilasciato l’evento. Questo “giusto” comportamento può tuttavia essere sovrascritto. Questo significa che per default this si riferisce all’oggetto che ha rilasciato l’evento. È stata introdotta anche la possibilità di creare eventi personalizzati. Altri miglioramenti riguardano la Function.prototype, le funzioni di DOM, Ajax, le funzioni delle classi e molto altro. Per una lista completa vedi il CHANGELOG.

Download

Continua...

Sviluppare applicazioni Adobe AIR con Aptana IDE

Adobe rilascia AIR (formerly code-named Apollo), acronimo di Adobe Integrated Runtime e, quindi, "successore" di Apollo. È possibile scaricare la versione beta rilasciata l’11 giugno qui: downloads AIR

Contemporaneamente viene rilasciata la build 0.2.8.15171 di Aptana IDE, ambiente di sviluppo eccezionale dedicato a sviluppatori HTML, PHP, Rails, Javascript ed ora anche con il supporto per AIR.

The Aptana IDE is a free, open-source, cross-platform, JavaScript-focused development environment for building Ajax applications. It features code assist on JavaScript, HTML, and CSS languages, FTP/SFTP support and a JavaScript debugger to troubleshoot your code.

Un temibile concorrente di Adobe Dreamweaver, almeno per i coders, visto che si tratta di un software gratuito integrabile, tra l’altro, con Eclipse. Misteriosamente, poi, Adobe ha rilasciato un’estensione per sviluppare applicazioni Adobe AIR solo per Dreamweaver CS3, abbandonando gli utenti della versione 8! Aptana, quindi, è un’ottima alternativa a Dreamweaver CS3, per chi vuole sperimentare lo sviluppo di package per Adobe AIR!

Tuttavia in Aptana la mancanza di una modalità WYSIWYG, ottima in Dreamweaver, ne diminuisce le potenzialità, che come già accennato sono indirizzate principalmente nell’editor di codice. Dreamweaver, in particolare con la release CS3, offre poi un’integrazione completa e ottimale con Flash CS3, Photoshop CS3 e tutti gli altri tools della nuovissima suite Creative Adobe, caratteristica completamente assente in ambienti IDE come Aptana.

L’IDE di Aptana, comuqnue sia, è spettacolare, comprensibile e dotata di tutte le caratteristiche vitali per un programmatore: gestione progetti, anteprime sui browser installati, autosalvataggio, confronto file, visualizzazione numeri di riga, editor completamente configurabile, collapse delle "taggature", XML incorporato, Debugger di alto livello, supporto italiano e moltissimo altro ancora.

Ottima la gestione della documentazione dinamica che permette di accedere alle specifiche W3C, Javascript e delle librerie (Web2.0 più note come Dojo, JQuery, Mootools, Yahoo (YUI) e Scriptaculous, tutto integrato in un unico ambiente nonostante la documentazione vera e propria venga prelevata direttamente dalla rete!

Aptana è disponibile per Windows (XP e Vista), Macintosh, Linux ed in Plugin per Eclipse. Sul sito sono disponibile moltissime features, compreso un Aptana.tv.

Insomma, per chi già sviluppa o per chi vuole iniziare a sviluppare applicazioni in Adobe AIR (qui troverete un tutorial video per iniziare lo sviluppo di applicazioni Adobe AIR), Aptana è un ambiente funzionale e confortevole, ottimamente integrato in rete e corredato anche da Plugin ed estensioni, alcune mirate per particolari browser come il debug per FireFox.

Ultima nota: alcune funzioni, come il Plugin per AIR, richiedono l’installazione delle runtime Java!

Continua...

Tabstrip Design

Per realizzare delle Tabstrip davvero accattivanti esiste una tecnica particolarmente indicata che consente di mediare tra difficoltà grafiche e codice Javascript. Vediamo prima di tutto come costruire un templete in Photoshop per le nostre Tabstrip:

Costruita un tabstrip simile a quella mostrata qui sopra in figura, usiamo il tool per la selezione delle area di taglio per generare la forma che avrà la nostra tabella HTML. L’uso della tabella, in questo caso, è particolarmente indicato – come vedremo, in quanto semplifica sia il design che il codice Javascript. Ritagliamo dunque la nostra Tabstrip nel modo seguente:

Nel nostro file Photoshop dobbiamo considerare tutte le combinazioni delle schede (tab). Abbiamo quindi la scheda iniziale selezionata (taglio 3), i punti intermedi (taglio 5 e taglio 7) e la scheda finale non selezionata (taglio 9) con – eventuale – bordo di rifinitura (taglio 10 – opzionale a seconda del design). Bastano poi 3 combinazioni per risolvere tutti i casi visivi. Come mostrato qui sotto:

Graficamente parlando potete disporre le schede anche in sovrapposizione e sfalsate, come mostrato qui sotto:

Questione di gusto e di necessità… tornando all’immagine completa, con le tre strisce Tabstrip per le combinazioni, le ultime due servono per risolvere i casi limite; tagliatele come mostrato qui sotto:

Il taglio 17 e il taglio 23 risolvono i due casi limite: prima tab non selezionata, ultima selezionata. Il taglio 19 è l’opposto del taglio 5 e del taglio 7, visti in precedenza. L’immagine completa che otteniamo e che possiamo salvare per futuri cambiamenti di design è la seguente:

Per non confonderci quando affronteremo la parte Javascript, il nome dei tagli è il seguente:

  • taglio 3 = tabLeftFirstOn
  • taglio 4 = tabStripeOn
  • taglio 5 = tabMiddleOnOff
  • taglio 6 = tabStripeOff
  • taglio 7 = tabMiddleOffOff
  • taglio 9 = tabRightLastOff
  • taglio 10 = topBg
  • taglio 17 = tabLeftFirstOff
  • taglio 19 = tabMiddleOffOn
  • taglio 23 = tabRightLastOn

Per realizzare tutto ciò ci serve adesso un codice HTML, un codice CSS e un codice Javascript come gestore dei click sulle schede tab. Il codice HTML è banale ma articolato. Quindi propongo una classe PHP in grado di generarlo ogni volta che ci serve. In sostanza si tratta di creare una tabella HTML racchiusa in determinati DIV con ID particolari che ci serviranno poi per l’esecuzione del codice Javascript e per racchiudere il design tramite i CSS. Il codice HTML generato – tanto per farsi un’idea – di un Tabstrip con quattro schede è il seguente:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
<div id="cscoTabStrip">
  <div id="jscoTabStrip_info">
    <table width="100%" cellspacing="0" cellpadding="0" border="0">
      <tr>
        <td><div class="tabLeftFirstOn"></div></td>
        <td nowrap="" class="tabStripeOn"><a id="jscoTS_tab1" onclick="_onTabStrip( this );" class="tabsLink" title="Caratteristiche">Caratteristiche</a></td>
        <td><div class="tabMiddleOnOff"></div></td>
        <td nowrap="" class="tabStripeOff"><a id="jscoTS_tab2" onclick="_onTabStrip( this );" class="tabsLink" title="Come funziona">Come funziona</a></td>
        <td><div class="tabMiddleOffOff"></div></td>
        <td nowrap="" class="tabStripeOff"><a id="jscoTS_tab3" onclick="_onTabStrip( this );" class="tabsLink" title="Interfaccia">Interfaccia</a></td>
        <td><div class="tabMiddleOffOff"></div></td>
        <td nowrap="" class="tabStripeOff"><a id="jscoTS_tab4" onclick="_onTabStrip( this );" class="tabsLink" title="Richiesta Iscrizione">Richiesta Iscrizione</a></td>
        <td><div class="tabRightLastOff"></div></td>
        <td width="100%" class="topBG"></td>
      </tr>
    </table>
  </div>
  <div id="jscoTSC_jscoTS_tab1" class="tabStripContent">
    <p>contenuto SCHEDA TAB 1</p>
  </div>
  <div id="jscoTSC_jscoTS_tab2" class="tabStripContentHidden">
    <p>contenuto SCHEDA TAB 2</p>
  </div>
  <div id="jscoTSC_jscoTS_tab3" class="tabStripContentHidden">
    <p>contenuto SCHEDA TAB 3</p>
  </div>
  <div id="jscoTSC_jscoTS_tab4" class="tabStripContentHidden">
    <p>contenuto SCHEDA TAB 4</p>
  </div>
</div>

Il codice PHP che genera questo HTML è il seguente:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
// ***********************************************************
//
// file     : tabstrip.php
// Author   : Giovambattista Fazioli (www.undolog.com)
// Web      : http://www.undolog.com
// E-mail   : info (at) undolog (dot) (com)
// Created    : 03/10/2005 10.07
// Modified   : 06/11/2005 07.17
//
// PROPERTIES
//  name    - (STRING)  - Nome (ID) della Window
//  style   - (STRING)  - Stile aggiuntivi in linea
//  tabs    - (ARRAY) - Elenco delle schede (tab)
//
// METHODS
//  addTab()  - Aggiunge una scheda al TabStrip
//  toString()  - Restituisce l'output HTML per la Window
//  show()    - Visualizza l'output HTML per la Window
//
// NOTE
//
// EXAMPLES
//
// ***********************************************************

class CSCO_UI_TABSTRIP {

  // #public properties
  var $name;
  var $style;
  var $tabs;
  var $jsListener;

  // #private properties
  var $strHeader;
  var $strBody;

  // =====================================================
  // CONSTRUCTOR:
  // =====================================================
  function CSCO_UI_TABSTRIP ( $name, $jsListener="" ) {
    $this->name     = $name;
    $this->jsListener = $jsListener;
    $this->tabs     = array();
  }

  // =====================================================
  // METHOD: addTab()
  //
  // DESCRIPTION
  //  Aggiunge una scheda al TabStrip.
  //
  // EXAMPLES
  //
  // =====================================================
  function addTab( $name, $label, $tooltip, $content, $selected=false ) {
    $tab = array( "name"    => $name,
            "label"   => $label,
            "tooltip"   => $tooltip,
            "content"   => $content,
            "selected"  => $selected );
    $this->tabs[] = $tab;      
  }

  // =====================================================
  // METHOD: toString()
  //
  // DESCRIPTION
  //  Restituisce l'output HTML per la TabStrip.
  //
  // EXAMPLES
  //
  // =====================================================
  function toString() {
    //
    $this->strHeader  = '<div id="cscoTabStrip" '.
                ( ($this->style != "")?'style="'.$this->style.'"':'' ).'>'.
                '<div '.
                'id="jscoTabStrip_'.$this->name.'">'.
                '<table style="border-collapse: collapse;" width="100%" border="0" cellspacing="0" cellpadding="0">'.
                '<tr>';
    $strBody = "";
    // FirstLeft
    $classLeft = ( $this->tabs[0]["selected"] )?"tabLeftFirstOn":"tabLeftFirstOff";
    $this->strHeader .= '<td><div class="'.$classLeft.'"></div></td>';       
    for($i=0; $i < sizeof($this->tabs); $i++) {
      //
      $classBck = ( $this->tabs[$i]["selected"] )?"tabStripeOn":"tabStripeOff";
      //
      if( $i == ( sizeof($this->tabs) -1) ) {
        $classMiddle = ( $this->tabs[$i]["selected"] )?"tabRightLastOn":"tabRightLastOff";
      } else {
        if( $this->tabs[$i]["selected"] ) {
          $classMiddle = "tabMiddleOnOff";
        } else {
          $classMiddle = ( $this->tabs[$i+1]["selected"] )?"tabMiddleOffOn":"tabMiddleOffOff";
        }
      }
      //
      //
      $this->strHeader .= '<td nowrap="nowrap" class="'.$classBck.'">'.
                '<a title="'.$this->tabs[$i]["tooltip"].'" class="tabsLink" onclick="_onTabStrip( this '.( ($this->jsListener!="")?(",'".$this->jsListener."'"):"" ).' );" id="jscoTS_'.$this->tabs[$i]["name"].'">'.$this->tabs[$i]["label"].'</a>'.
                '</td>'.
                '<td><div class="'.$classMiddle.'"></div></td>';
      //             
      $class = ($this->tabs[$i]["selected"])?"tabStripContent":"tabStripContentHidden";
      $strBody .= '<div class="'.$class.'" id="jscoTSC_jscoTS_'.$this->tabs[$i]["name"].'">'.$this->tabs[$i]["content"].'</div>';
      //
    }
    // align foo
    $this->strHeader .= '<td class="topBG" width="100%"></td>'.
              '</tr></table>';
   
    $this->strBody   =  '<div>'.$strBody.'</div>';
    //
    return( $this->strHeader.$this->strBody.'</div></div>');
  }

  // =====================================================
  // METHOD: show()
  //
  // DESCRIPTION
  //  Visualizza l'output HTML per la TabStrip.
  //
  // EXAMPLES
  //
  // =====================================================
  function show() {
    echo ( $this->toString() );
  }
 
} // END OF SCO_UI_TABSTRIP.PHP FILE

Per usare la classe basta questo frammento:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
// File con la definizione della class
require "tabstrip.php";

// Creo oggetto Tabstrip
$t =  new CSCO_UI_TABSTRIP( "info" );

// Creo / leggo da file - i contenuti delle schede
$s1 = "Contenuto 1";
$s2 = "Contenuto 2";
$s3 = "Contenuto 3";
$s4 = "Contenuto 4";

// Aggiungo schede 
$t->addTab("tab1","Caratteristiche","Caratteristiche", $s1, true);
$t->addTab("tab2","Come funziona","Come funziona", $s2);
$t->addTab("tab3","Interfaccia","Interfaccia", $s3);
$t->addTab("tab4","Richiesta Iscrizione","Richiesta Iscrizione", $s4);

// Mostro tutto - in alternativa usare toString() method
$t->show();

Definiamo ora gli stili:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
div#cscoTabStrip  {font-size:13px}

div#cscoTabStrip .tabStripeOff a.tabsLink,
div#cscoTabStrip .tabStripeOff a.tabsLink:link,
div#cscoTabStrip .tabStripeOff a.tabsLink:visited {display:block;cursor:pointer;white-space:nowrap;color:#888;margin:0 4px 0 4px}
div#cscoTabStrip .tabStripeOff a.tabsLink:hover   {color:#f70}

div#cscoTabStrip .tabStripeOn a.tabsLink,
div#cscoTabStrip .tabStripeOn a.tabsLink:link,
div#cscoTabStrip .tabStripeOn a.tabsLink:visited  {display:block;cursor:pointer;white-space:nowrap;color:#000;font-weight:bold;margin:0 4px 0 4px}
div#cscoTabStrip .tabStripeOn a.tabsLink:hover  {}


div#cscoTabStrip .tabLeftFirstOff {display:block;width:20px;height:35px;background:url(tabstrip/tabLeftFirstOff.png) no-repeat;}
div#cscoTabStrip .tabLeftFirstOn  {display:block;width:20px;height:35px;background:url(tabstrip/tabLeftFirstOn.png) no-repeat;}

div#cscoTabStrip .tabMiddleOffOff {display:block;width:20px;height:35px;background:url(tabstrip/tabMiddleOffOff.png) no-repeat;}
div#cscoTabStrip .tabMiddleOffOn  {display:block;width:20px;height:35px;background:url(tabstrip/tabMiddleOffOn.png) no-repeat;}
div#cscoTabStrip .tabMiddleOnOff  {display:block;width:20px;height:35px;background:url(tabstrip/tabMiddleOnOff.png) no-repeat;}
div#cscoTabStrip .tabStripeOff    {background:url(tabstrip/tabStripeOff.png) repeat-x;}
div#cscoTabStrip .tabStripeOn   {background:url(tabstrip/tabStripeOn.png) repeat-x;}

div#cscoTabStrip .tabRightLastOff {display:block;width:20px;height:35px;background:url(tabstrip/tabRightLastOff.png) no-repeat;}
div#cscoTabStrip .tabRightLastOn  {display:block;width:20px;height:35px;background:url(tabstrip/tabRightLastOn.png) no-repeat;}
div#cscoTabStrip .topBG       {text-align:right;background:url(tabstrip/topBg.png) repeat-x;}

div#cscoTabStrip .tabStripContent   {width:100%;padding:0;}
div#cscoTabStrip .tabStripContentHidden {display:none;}

Il codice Javascript è assai blando, scritto in un’epoca lontata quando Prototype.js non esisteva. Inoltre nell’esempio qui sotto faccio uso di una libreria di effetti (non esisteva nemmeno Scriptaculous) ancora valida, quindi la riga che usa la transizione Opacity la potete sostituire con quello che volete:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
function _onTabStrip(t) {
  if( arguments.length > 1 ) {
    var evt = "onBeforeClick";
    var n   = t.id.substr(7);
    var e = "var res = "+arguments[1]+"('"+n+"','"+evt+"');";
    eval(e);
    if(!res) return(false);
  }
  var tr = t.parentNode.parentNode;
  for(var i = 1; i < tr.childNodes.length-2; i++ ) {
    var td = tr.childNodes[i];
    var el = td.childNodes[0];
    //
    switch( el.tagName ) {
      case "DIV":
        el.className = "tabMiddleOffOff";
        break;
      case "A":
        td.className = "tabStripeOff";
        break; 
    }
  }
  var td = t.parentNode;
  td.previousSibling.childNodes[0].className = "tabMiddleOffOn";
  td.nextSibling.childNodes[0].className = "tabMiddleOnOff";
  tr.childNodes[0].childNodes[0].className = ( tr.childNodes[1].childNodes[0] === t )?"tabLeftFirstOn":"tabLeftFirstOff";
  var last = Number( (tr.childNodes.length-2) );
  tr.childNodes[last].childNodes[0].className = ( tr.childNodes[last-1].childNodes[0] === t )?"tabRightLastOn":"tabRightLastOff";
  t.parentNode.className = "tabStripeOn";
  var mc  = $G( "jscoTSC_"+t.id );
  var d = mc.parentNode;
  for (var i = 0; i < d.childNodes.length; i++) {
    d.childNodes[i].className = "tabStripContentHidden";
  }
  mc.className = "tabStripContent";
  var to = new OpacityTween(mc,Tween.regularEaseOut, 0, 100, 1);
  to.t = t; to.args = arguments;
  to.onMotionFinished = function() {
    if( this.args.length > 1 ) {
      var evt = "onAfterClick";
      var n   = this.t.id.substr(7);
      var e = "var res = "+this.args[1]+"('"+n+"','"+evt+"');";
      eval(e);
    }
  };
  to.start();  
}

In pratica le righe dalla 36 alle 46 possono essere sostituite con quello che volete, anche un display=”none”. Il codice è antiquato, almeno rispetto le nuove tecniche di Javascript non intrusivo (oggi lo scriverei in modo diverso). Tuttavia la parte che rimane interessante ed attuale e la configurazione della tabella HTML che gestisce i Tabstrip. Essa permette una resa grafica di alto livello, a differenza di alcuni altri metodi che – in sostanza – trattano le schede Tab come semplici DIV uno accanto all’altro.
Un modo ancora migliore sarebbe quello di sfruttare lo z-index (ordine di visualizzazione) presente negli stili CSS, così da gestire la sovrapposizione di elementi grafici. Purtroppo, ad oggi, è una tecnica assai difficile da implementare a causa delle differenze tra i browser che la rendono di fatto instabile, salvo rare circostanze.
Presto ne farò una versione più moderna… se avete dubbi o domande sono qui!

Continua...

Restyling: animazioni ed interattività

Dopo aver sistemato la grafica di Undolog e aver apportato gli ultimi ritocchi ad alcuni titoli (vedi sidebar), mi sono divertito ad usare l’accoppiata Prototype.js e Scriptaculous, in modalità non intrusiva (Unobtrusive)! Ecco un video (ma lo potete provare di persona qui a destra ;) ) con la simpatica funzione che ho aggiunto alla sidebar di Undolog, che oltre a renderla più gradevole spero la renda anche più funzionale!

Loading Flash Player...

Il codice che ho utilizzato è davvero semplice:

1
2
3
4
5
6
7
8
9
Event.observe(window, 'load', function() {
  $$('h2.dropdown').each( function(element) { element.style.cursor="pointer";
    element.observe('click', function(event) {
    if( this.next().style.display == "" ) new Effect.BlindUp(this.next(),{duration:.5});
    else new Effect.BlindDown(this.next(),{duration:.3});
    Event.stop(event);
  }.bindAsEventListener(element))
  })
})

Inoltre notate che la prima volta che viene caricata la Home Page di Undolog viene automaticamente chiuso il pannello delle Categorie – identificato dall’id tit_category:

1
Event.observe(window, 'load', function() {new Effect.BlindUp($("tit_category").next(),{duration:.5}) } )

I titoli sulla sidebar sono definiti, quindi, in questo modo:

1
2
3
4
<h2 id="tit_category" class="dropdown replacetitle" title="Categorie"><span>Categorie</span></h2>
<div>
    <p>Contenuto da far sparire!</p>
</div>

Tramite la classe dropdown vengono identificati i titoli H2 da rendere dinamici, grazie alla funzione doppio-dollaro ($$) di Prototype.js – di cui abbiamo già parlato…

Continua...

Accessibilità e Usabilità: unobtrusive Javascript

Permettere agli utenti di interagire con una pagina Web ha prodotto negli ultimi anni un notevole aumento nell’uso di script lato client: codice Javascript in grado di rispondere e manipolare in tempo reale tutta una serie di informazioni. Il Web2.0 è la massima espressione di questa capacità di interazione, dove l’utente finale – il navigatore -partecipa attivamente alla costruzione e all’evoluzione del sito Web, interagendo con esso e contribuendo personalmente. Si parla quindi di User-Generated Content (o UGC – contenuto generato dagli utenti) che vede il “navigatore” sicuramente meno passivo!

Per realizzare questa interazione, per permettere quindi all’utente finale di aggiungere il suo contributo, sono state sviluppate una serie di tecniche che hanno modificato l’aspetto e il comportamento delle pagine Web (statiche sino ad oggi, mentre adesso simili alle tradizionali applicazioni dei Desktop) negli ultimi anni. Modificare il contenuto di una pagina, inviare dei file, dare il proprio voto ad un video o a un documento, registrarsi o modificare i propri dati, sono solo alcune delle operazioni richeste in tanti servizi (2.0 beta) presenti sul Web.

Continua...

Reverse Engineering: i compressori di codice

Una questione trascurata nell’ambito del Web2.0 è la protezione del codice sorgente. In un ottica Open Source, dove il Web2.0 trova nella beta la sua massima espressione, condividere e far partecipare la comunità lascia sicuramente in secondo piano questioni legate alla protezione del codice sorgente. Ricordiamo, infatti, che gli script Javascript vengono scaricati all’interno del browser dal Web Server, come file testuali, quindi totalmente visibili all’utente finale.
Mentre il codice Server è protetto per definizione (è impossibile accedere al codice di una pagina PHP tramite il protocollo HTTP del browser, salvo i rari casi di malfuzionamento del Web Server), il codice client potrebbe essere soggetto ad un Reverse Engineering.

Esiste tuttavia una semplice protezione ideata, ai suoi esordi, per dimuire la dimensioni degli script Javascript; oggi diventati veri e propri framework in alcuni casi.
Esistono infatti applicativi e siti Web che permettono di comprimere (crunch) il codice Javascript, ma non solo. Questa caratteristica, in modalità diversa, può essere applicata anche al codice HTML e ai fogli di stile CSS. Il codice Javascript, in particolare, oltre ad essere compresso può essere nascosto, ottenendo così una protezione del codice (a vista) tale da rendere più articolata la procedura di Reverse Engineering.

Le differenze tra HTML, CSS e Javascript sono importanti e sostanziali. Mentre la compressione di pagine HTML e fogli di stile può solo agire sull’eliminazione di caratteri inutili o superflui, come ‘a capo’, ‘spazi doppi’, ecc…, Javascript è un linguaggio di programmazione che può quindi eseguire uno speciale codice per decomprimere se stesso.

JavascriptCompressor.com è un servizio gratuito, utilizzabile online, che permette di comprime un codice sorgente Javascript. Le opzioni lo rendono estremamente versatile, garantendo al contempo l’oscuramento del codice.

Esempio, codice di partenza:

1
2
3
function MyFunction() {
  alert("Hello World");
}

Codice con compressione semplice:

1
function MyFunction(){alert("Hello World")}

Encoding normale:

1
eval(function(p,a,c,k,e,d){while(c--)if(k[c])p=p.replace(new RegExp('\\b'+c+'\\b','g'),k[c]);return p}('4 3(){2("1 0")}',5,5,'World|Hello|alert|MyFunction|function'.split('|')))

Ovviamente questo è un esempio, con codici piccoli comprimere non ha davvero molto senso, si rischi di peggiorare le cose e basta (a meno che non siate interessati esclusivamente all’oscuramento del codice a vista).

MemTronic Cruncher Compressor è anch’esso un servizio online (come il precedente funzionano anche in modalità offline) parzialmente gratuito, nel senso che alcune funzioni sono disponibili solo nella versione a pagamento (come la funzione Obfuscade). Rispetto al precedende servizio dovrebbe offrire maggiori prestazioni e sicurezza nel crittaggio del codice. Io li uso indistintamente, a seconda dei casi.

Peterbe.com non permette di comprimere Javascript (salvo che elimando spazi e ‘a capo’), ma propone un compressor per HTML, CSS e XHTML. Io, ad esempio, lo uso per comprimere i fogli di stili.

A meno di usare algoritmi particolari di crunching, che tuttavia appesantirebbero l’elaborazione dei dati, è sempre possibile eseguire un Reverse Engineering del codice, anche quello compresso. O presto o tardi, infatti, il codice originale deve essere inviato all’interprete del browser, il quale lo riconosce (per ora) solo in chiaro. In un futuro, con nuove versioni dei browser, questo impedimento potrebbe essere superato. Sarebbe infatti vantaggioso se venisse implementata, all’interno dei browser, una qualche tecnologia in grado di accettare codice Javascript pre-compilato, in binario per intenderci (caso mai crittato). In questo modo si abbatterebbero i tempi di download degli script, consentendo una naturale protezione dal Reverse Engineering e, non ultimo, maggior performance a livello di esecuzione degli script.

Continua...

Web2.0: Gran Paradiso-Firefox 3.0 e Apollo

È disponibile online la versione Alpha 2 di Firefox 3.0, nome in codice Gran Paradiso. Tra le novità annunciate (la versione definitiva è attesa per fine 2007) troviamo la possibilità di utilizzare il browser in modalità off-line. Tutto questo ricorda Adobe Apollo che, nonostante non si presenti come browser, ne evoca i tratti essenziali.

Continua...

Web2.0: Adobe ci prova con Apollo?

Apollo è il nome in codice (per ora) di un ambizioso progetto Adobe destinato al mondo  RIA (Rich Internet Applications) e Web2.0, Ajax compreso. A qualcuno ricorda Macromedia Contribute, a qualcun’altro Macromedia Central. C’è, altresì, chi vede in Apollo la mera unione -  o possibilità – di far convivere elementi Flash e PDF (cosa tra l’altro già fattibile con Flash Paper)!

Continua...

Nascondimi

Una caratteristica dei fogli di stili (i file .css) è quella di poter essere specificati a seconda del media di output. Gli Style Sheet permettono infatti di specificare la stessa classe, lo stesso ID lo stesso TAG, ecc… per media diversi. Ad esempio posso scrivere un file .css con la seguente sintassi:

1
2
3
4
5
6
7
@media screen {
div#myBox {display:none}
}

@media print {
div#myBox {display:block}
}

Quello che ne deriva, alla fine, è che il contenuto del DIVcon id myBoxnon sarà visibile sul browser, sullo schermo, ma quando provo a stampare la pagina troverò un contenuto diverso da quello che mi aspettavo.
I motori di ricerca, spider, crawler o aggregatori, normalmente (per ora) non risolvono i file css. A loro interessa il contenuto non la formattazione visiva. Tuttavia questa tecnica potrebbe avere risvolti interessanti se non inquietanti. Proprio per le caratteristiche dei sistemi di indicizzazione una situazione come quella mostrata qui sotto sarebbe quantomeno curiosa:

1
2
3
4
5
6
7
<div id="visibile_a_video">
   <p>Contenuto visibile a video</p>
</div>

<div id="visibile_in_stampa">
   <p>Contenuto visibile in stampa</p>
</div>

Correlato con un file .css di questo tipo:

1
2
3
4
5
6
7
8
9
@media screen {
div#visibile_a_video {display:block}
div#visibile_in_stampa {display:none}
}

@media print {
div#visibile_a_video {display:none}
div#visibile_in_stampa {display:block}
}

Google, ad esempio, indicizzerebbe entrambi i contenuti del nostro HTML, anche se a video saremmo in grado di vederne solo uno. Se stampiamo la pagina troveremmo con sorpresa un nuovo contenuto. Il trucco, tuttavia, sarebbe svelato eliminando l’applicazione degli stili nei browser che lo supportano. Normalmente nessuno esegue un’operazione di questo tipo quando naviga su Internet. Tale indagine scaturirebbe solo dopo aver trovato un’incongruenza tra ciò che è visibile a video e ciò che si è stampato!

Ad oggi non mi risultano casi eclatanti di questo tipo di manipolazioni tramite CSS. Un tempo si cercava di aumentare la visibilità su Internet inserendo una serie di testi, parole, dello stesso colore dello sfondo della pagina Web, così da rendere tale artifizio oscuro agli occhi dei navigatori. Con il tempo i motori di indicizzazione si sono cautelati contro queste “frodi”. Sarà forse il momento di anticipare qualche burlone prima di creare un precedente?

Attualmente gli Style Sheet consentono di specificare tutta una serie di media type di output. Per una lista completa vedi il W3C.

Continua...



Stop SOPA