Articoli con Tag ‘Internet’


Consigli folli da Microsoft: JScript vs Javascript (parte 1)

Ormai da Microsoft ci aspettiamo davvero di tutto, soprattutto quando si parla di browser. Offendere l’intelligenza della comunità, tuttavia, risulta un po’ sgradevole da accettare.
Sul Blog di IE7 è uscito oggi un articolo (IE+JScript Performance Recommendations Part 3: JavaScript Code Inefficiencies), se così possiamo definirlo di Peter Gurevich, Performance PM for IE, con la parte III dei suoi “consigli” per gli sviluppatori.

Primo appunto: perchè Microsoft si ostina ad implementare una sua versione di Javascript – che chiama appunto JScript – complicando la vita a tutti?

Secondo appunto: proprio perchè il motore di JScript è proprietà della Microsoft, invece di perdere tempo a dire a “noi” come aggirare i difetti, perchè non li sistemano una volta per tutte?

Lasciando stare il primo consiglio di questa III parte, che potete leggere direttamente sul Blog o su Ajaxian, il secondo è davvero eclatante, e sinceramente non lo diregisco proprio.

Don’t use Property Accessor Functions

Quando si dice il progresso! In pieno 2007, un Project Manager della Microsoft viene a dire a noi sviluppatori di Non usare le funzioni di get e set in JScript!
La follia, evidentemente, è uno strano male, che colpisce in modo repentino e fuorviante. JScript – sullo stile di Javascript – è implementato seguendo un modello ad oggetti! È un linguaggio ad oggetti, sulla scia del C++. Il fatto che le variabili siano accessibili dall’esterno (come sottolineato nell’articolo – cosa ovvia tra l’altro) non è assolutamente un vanto, anzi. La tecnica dell’incapsulamento è propria della filosofia della programmazione OO. Incapsulare le proprietà, passando dai virtual-method get e set è una forza del linguaggio Object Oriented, non un limite. Consigliare di non farne uso è a dir poco criminale, e gli eventuali problemi di performance sono a carico dell’interprete e dei suoi autori, non certo dell’end-developer.
Quindi, alla fine, JScript va usato come un semplice C, guai a trattarlo come C++, pena “impallare” il browser o chissà cos’altro.

Inoltre, come segnalato sul Blog, il tutto è un falso problema in quanto JScript NON implementa le vere funzioni di get e set, solo Javascript lo fa!

Ma il problema, evidentemente, rimane. In Javascript (scusate ma JScript non riesco proprio a digerirlo) ci sono varie tecniche per creare un oggetto. Ad esempio lo si può creare in modo immediato in questo modo:

1
2
3
4
5
   var myObject = {
       miaProprieta: 0,

       mioMethodo: function() { alert("Hello"); }
   };

In questo modo non ho dichiarato una classe. L’oggetto viene per così dire dichiarato e creato contemporaneamente. È un modo rapido quando l’oggetto che ci serve è unico.

Oppure, il che è equivalente ai fini pratici:

1
2
3
4
5
6
7
8
function CmyObject() {
    this.miaProprieta = 0;

    this.mioMetodo = function () { alert("Hello") }

}
//
var iMyObject = new CmyObject();

In questo caso prima si definisce la classe – tramite una function- (CmyObject) e poi si crea esplicitamente l’oggetto con new.

A parte le questioni stilistiche relative al singolo sviluppatore, il problema di come accedere alle proprietà di una classe rimane. Consiglio vivamente a tutti gli interessati, comumque, di leggere le risposte al Blog di Microsoft, davvero interessanti.

Sul Blog erano presenti tre modi di accesso: con le funzioni get e set, diretto e passando da prototype. Alla fine la cosa simpatica è stata che sul Blog c’è un codice per eseguire un Testdrive, una prova dei tre metodi indicati sopra. Il codice è presente sul Blog ma lo riporto qui per completezza:

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
<script>
// Slow Car definition
function SlowCar()
{
      this.m_tireSize = 17;
      this.m_maxSpeed = 250; // One can always dream!
      this.GetTireSize = SlowCar_get_tireSize;
      this.SetTireSize = SlowCar_put_tireSize;
}
function SlowCar_get_tireSize()
{
      return this.m_tireSize;
}
function SlowCar_put_tireSize(value)
{
      this.m_tireSize = value;
}
</script>


<script>
// Faster Car, no more property accessors
function FasterCar()
{
      this.m_tireSize = 17;
      this.m_maxSpeed = 250; // One can always dream!
}
</script>


<script>
// Prototype Car, use the language features!
function PrototypeCar()
{
      this.m_tireSize = 17;
      this.m_maxSpeed = 250; // One can always dream!
}

PrototypeCar.prototype.GetTireSize = function() { return this.m_tireSize; };
PrototypeCar.prototype.SetTireSize = function(value) { this.m_tireSize = value; };
</script>


<script>
function TestDrive()
{
      var slowCar = new SlowCar(); // Safe and reliable, probably not fast
      var fasterCar = new FasterCar(); // Lacks air-bags, probably faster
      var protoCar = new PrototypeCar(); // Can technology win the day?


      var start = (new Date()).getTime();
      for(var i = 0; i < 100000; i++) { slowCar.SetTireSize(slowCar.GetTireSize() + 1); }
      var end = (new Date()).getTime();
      output.innerHTML += "Slow Car " + (end - start) + "<br>";
     

      start = (new Date()).getTime();
      for(var i = 0; i < 100000; i++) { fasterCar.m_tireSize += 1; }
      end = (new Date()).getTime();
      output.innerHTML += "Faster Car " + (end - start) + "<br>";


      start = (new Date()).getTime();
      for(var i = 0; i < 100000; i++) { protoCar.SetTireSize(protoCar.GetTireSize() + 1); }
      end = (new Date()).getTime();
      output.innerHTML += "Prototype Car " + (end - start) + "<br>";
}
</script>

<button onclick="TestDrive();">Test Drive Cars!</button>
<div id="output"></div>

Ora, questo è l’output (relativo alla mia macchina) con IE7:
Slow Car 515
Faster Car 63
Prototype Car 547

Con FireFox (v.2.0.0.1):
Slow Car 156
Faster Car 47
Prototype Car 172

Con Opera (v.9.10):
Slow Car 172
Faster Car 47
Prototype Car 172

Insomma :) IE7 ne esce davvero male… non so se notate l’enorme differenza. Quindi direi che JScript potrebbe essere abolito, eliminato, cancellato, vaporizzato. Speriamo che Microsoft si decida anche lei ad adottare Javscript e non i surrogati.

Continua...

5 motivi per passare a Internet Explorer 7 (IE7)

È giunto il momento di prendere una decisione. L’anno 2007 è ormai avviato ed è quindi inutile indulgiare ulteriormente. Microsoft Vista è alle porte, e il 2008 sarà il suo anno. Windows XP sta per lasciare il posto all’ultimo nato in casa Gates, ultimo – tra l’altro – del suo genere.
Quindi risulta ovvio – se qualcuno non se ne fosse ancora accorto – una certa urgenza nell’aggiornare lo strumento più utilizzato del secolo (se non del millennio), ovvero il browser.

Rilasciato da poco come aggiornamento automatico – ma facoltativo per motivi di monopolio e antitrust – Microsoft Intrenet Explorer 7 diventa per i possessori di Windows una scelta obbligata. L’aggiornamento è vivamente consigliato soprattutto per motivi di sucurezza e accessibilità sul Web. La scoperta di falle nei codici non è cosa nuova, ma le ultimi versioni sono notoriamente meno attaccabili in quanto gli hackers non hanno avuto il tempo di scoprire i buchi da cui insinuare hacks e worm.

Ecco quindi 5 buoni motivi, secondo me, per passare da subito a Internet Explorer 7 (IE7):

  1. È il browser delle prossime generazioni, quindi meglio prendere subito dimestichezza con le sue nuove funzionalità
  2. Migliore stabilità e sicurezza
  3. Migliore assistenza sugli aggiornamenti e supporto dei componenti aggiuntivi
  4. Migliore navigabilità sul Web, dove la tecnologia utilizzata in IE7 si avvicina meglio a quella già presente in altri noti browser come FireFox, Opera, ecc… così – finalmente – riuscirete a vedere correttamente alcuni siti Web, navigabili oggi solo con FireFox

Perchè rimanere indietro? ;)

Continua...

Classi Javascript e PHP per validare un’indirizzo di posta elettronica

Riprendendo il post Validare email in Javascript e PHP, ecco una simpatica classe Javascript in grado di verificare e controllare indirizzi di posta elettronica. Il suo uso è davvero semplice, anche se è un controllo lato client, quindi facilmente bypassabile; basta infatti disabilitare Javascript (propongo petizione contro questa possibilità ;) oramai tutti i browser permettono di eludere Javascript, e quindi tutti i controlli associato – a breve non funzionerà più nulla su Internet, vedi Ajax :o ).

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
/*
** @name              : ckmail.js
** @description       : Check email syntax
** @author            : =undo=
** @author-web        : http://www.undolog.com
** @author-email      : g.fazioli@undolog.com - g (dot) fazioli (at) undolog (dot) com
** @date              : 21/09/2006 21.24
** @ver               : 1.0
*/


var oCKMail = {
    __release: "1.0",
    __filter: /^([\w-]+(?:\.[\w-]+)*)@((?:[\w-]+\.)*\w[\w-]{0,66})\.([a-z]{2,6}(?:\.[a-z]{2})?)$/i,
    __username: "",
    __domain: "",
    __ext: "",

    // TO DO
    getUsername: function(e) {
        if(this.__init(e)) return(this.__username);
        return(false);
    },

    // TO DO
    getDomain: function(e) {
        if(this.__init(e)) return(this.__domain);
        return(false);
    },

    // TO DO
    getExtension: function(e) {
        if(this.__init(e)) return(this.__ext);
        return(false);
    },

    // TO DO
    __init: function(e) {
        if( !this.__filter.test(e) ) return(false);
        var t = e.split("@");
        this.__username = t[0];
        this.__domain = t[1];
        t = this.__domain.split(".");
        this.__ext = t[1];
        return(true);
    },

    // TO DO
    // synopsis
    //    check(e,extlist,domainlist);
    // Esegue una serie di controlli standard su un indirizzo e-mail.
    //    extlist        - Si pu&ograve; passare un secondo parametro opzionale che corrisponde ad un array di estensioni che
    //                   sono ammesse o escluse (include/exclude extension) in base al primo valore dell'array, tutte le
    //                   altre saranno considerate errore.
    //                   Eg. [true,"it","com"] passano (include list)
    //                   Eg. [false,"it","com"] NON passano (exclude list)
    //                   Se -1 non viene preso in considerazione
    //    domainlist    - Si pu&ograve; passare un terzo parametro opzionale che corrisponde ad un array di domini che
    //                   sono ammessi o esclusi (include/exclude domain) in base al primo valore dell'array, tutte gli
    //                   altri saranno considerate errore.
    //                   Eg. [true,"alice.it","mac.com"] passano (include list)
    //                   Eg. [false,"alice.it","mac.com"] NON passano (exclude list)
    //                   Se -1 non viene preso in considerazione
    //
    check: function(e) {
        if( this.__init(e) ) {
            // check domainExt array check
            if( arguments.length > 1 ) {
                if( typeof( arguments[1] ) == "object" ) {
                    if( arguments[1][0] ) { // include list
                        for(var i=0; i < arguments[1].length; i++) {
                            if( this.__ext == arguments[1][i].toLowerCase() ) return(true);
                        }
                    } else { // exclude list
                        for(var i=0; i < arguments[1].length; i++) {
                            if( this.__ext == arguments[1][i].toLowerCase() ) return(false);
                        }
                        return(true);
                    }
                    return(false);
                }
            }
            // check domainName array check
            if( arguments.length > 2 ) {
                if( typeof( arguments[2] ) == "object" ) {
                    if( arguments[2][0] ) { // include list
                        for(var i=1; i < arguments[2].length; i++) {
                            if( this.__domain == arguments[2][i].toLowerCase() ) return(true);
                        }
                    } else { // exclude list

                        for(var i=1; i < arguments[2].length; i++) {
                            if( this.__domain == arguments[2][i].toLowerCase() ) return(false);
                        }
                        return(true);
                    }
                    return(false);
                }
            }
            return(true); // email correct
        }
        return(false); // error
    }
};

L’oggetto oCKMail mette a disposizione alcuni metodi per effettuare tutta una serie di controlli paralleli sull’indirizzo, come l’estensione, il dominio, ecc…

Per essere proprio sicuri se disponete di PHP potete aggiungere un’ulteriore ed efficace controllo prima di eseguire il comando mail(). Ecco la classe PHP utile a tale scopo:

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
/*
** @name              : cckmail.php
** @description       : Check email syntax
** @author            : =undo=
** @author-web        : http://www.undolog.com
** @author-email      : g.fazioli@undolog.com - g (dot) fazioli (at) undolog (dot) com
** @date              : 21/09/2006 23.58
** @ver               : 1.0
**
** EXAMPLES
**
**    // Controlla un indirizzo ESCLUDENDO quelle e-mail con dominio "e-lementi.com" e "mac.com"
**
**    $oCKMail = new CCKMail();
**    $oCKMail->check($email, NULL, array(false,"e-lementi.com","mac.com") );
**
**    // Controlla un indirizzo INCLUDENDO quelle e-mail con dominio "e-lementi.com" e "mac.com"
**
**    $oCKMail = new CCKMail();
**    $oCKMail->check($email, NULL, array(true,"e-lementi.com","mac.com") );
**
**    // Controlla un indirizzo ESCLUDENDO quelle e-mail con estensione "net","it","org"
**
**    $oCKMail = new CCKMail();
**    $oCKMail->check($email, array(false,"net","it","org") );
**
** HISTORY / CHANGE LOG
**
*/


    if (!function_exists('checkdnsrr')) {
        function checkdnsrr($host, $type = '') {
            if(!empty($host)) {
                if($type == '') $type = "MX";
                @exec("nslookup -type=$type $host", $output);
                while(list($k, $line) = each($output)) {
                    if(eregi("^$host", $line)) {
                        return true;
                    }
                }
                return false;
            }
        }
    }
    //
    class CCKMail {
        var $__release = "1.1";
        var $status = false;
        var $username;
        var $domain;
        var $ext;
        //
        function CCKMail() {}
        //
        function _test($e) {
            $this->status = false;
            $p = '/^.+\@(\[?)[a-zA-Z0-9\-\.]+\.([a-zA-Z]{2,4}|[0-9]{1,3})(\]?)$/';
            if( (preg_match($p, $e)) ) {
                $t               = explode("@",$e);
                $this->username  = strtolower( $t[0] );
                $this->domain    = strtolower( $t[1] );
                $t               = explode(".",$this->domain);
                $this->ext       = strtolower( $t[1] );
                //
                if(checkdnsrr($this->domain.'.', 'MX') )    $this->status = true;
                if(checkdnsrr($this->domain.'.', 'A') )     $this->status = true;
                if(checkdnsrr($this->domain.'.', 'CNAME') ) $this->status = true;
            }
        }
        //
        function check($m, $e=NULL,$d=NULL) {
            $this->_test($m);
            if( $this->status ) {
                // check domainExt array check
                if( !is_null($e) ) {
                    if( $e[0] ) { // include list
                        for($i=1; $i < sizeof($e); $i++) {
                            if( $this->ext == strtolower( $e[$i] ) ) return(true);
                        }
                    } else { // exclude list
                        for($i=1; $i < sizeof($e); $i++) {
                            if( $this->ext == strtolower( $e[$i] ) ) return(false);
                        }
                        return(true);
                    }
                    return(false);
                }
                // check domainName array check
                if( !is_null($d) ) {
                    if( $d[0] ) { // include list
                        for($i=1; $i < sizeof($d); $i++) {
                            if( $this->domain == strtolower( $d[$i] ) ) return(true);
                        }
                    } else { // exclude list
                        for($i=1; $i < sizeof($d); $i++) {
                            if( $this->domain == strtolower( $d[$i] ) ) return(false);
                        }
                        return(true);
                    }
                    return(false);
                }
                return(true);
            }
            return(false);
        }
    }
?>

La cosa ineteressante è la capacità di questa classe di connettersi ai server MX (vedi checkdnsrr() ) per verificare la presenza del dominio. Quindi oltre ad eseguire un controllo sintattico sull’indirizzo di posta elettronica viene eseguito un vero e proprio ping del dominio passato. Possiamo dire che questo metodo è sicuro all’80%…

Continua...

Classe Javascript per il rilevamento di Flash

Anche se non si realizza un sito interamente in Flash, alcuni componenti possono presentarsi comunque all’interno della pagina, come banner, claim, visori RSS, ecc… Eco quindi un modo semplice per verificare se Flash è attivo e installato. Proponiamo qui un metodo che non necessità di più pagine, come proposto dalla stessa Adobe. Faremo in modo di risolvere tutto all’interno di un’unica pagina.

La classe qui presentata permette anche di risolvere l’ultimo problema nato con Explorer, ovvero quello dell’attivazione di un controllo ActiveX. Per risolverlo basta utilizzare Javascript per inserire il componente Flash, proprio quello che fa la nostra classe.

La prima cosa di cui abbiamo bisogno è una simpatica classe Javascript che ci permetterà di eseguire tutti i controlli necessari:

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
<!--
  /*
  ** Detect Flash Class & Path insertFlash Object
  **
  */


var df = {
  __release: "1.0",
  _isIE: ( (navigator.appVersion.indexOf("MSIE") != -1) ? true : false),
  _isWin:( (navigator.appVersion.toLowerCase().indexOf("win") != -1) ? true : false),
  _isOpera:( (navigator.userAgent.indexOf("Opera") != -1) ? true : false),
 
  getSwfVer: function (i) {
    // Le versioni di NS/Opera dalla 3 in poi verificano la presenza del plug-in Flash nell'array dei plug-in
    if (navigator.plugins != null && navigator.plugins.length > 0) {
      if (navigator.plugins["Shockwave Flash 2.0"] || navigator.plugins["Shockwave Flash"]) {
        var swVer2 = navigator.plugins["Shockwave Flash 2.0"] ? " 2.0" : "";
            var flashDescription = navigator.plugins["Shockwave Flash" + swVer2].description;
        var descArray = flashDescription.split(" ");
        var tempArrayMajor = descArray[2].split(".");
        var versionMajor = tempArrayMajor[0];
        var versionMinor = tempArrayMajor[1];
        if ( descArray[3] != "" ) var tempArrayMinor = descArray[3].split("r");
        else var tempArrayMinor = descArray[4].split("r");
        //
            var versionRevision = tempArrayMinor[1] > 0 ? tempArrayMinor[1] : 0;
              var flashVer = versionMajor + "." + versionMinor + "." + versionRevision;
          } else  var flashVer = -1;
    }
    else if (navigator.userAgent.toLowerCase().indexOf("webtv/2.6") != -1) flashVer = 4;
    else if (navigator.userAgent.toLowerCase().indexOf("webtv/2.5") != -1) flashVer = 3;
    else if (navigator.userAgent.toLowerCase().indexOf("webtv") != -1) flashVer = 2;
    else flashVer = -1;
    //
    return flashVer;
  },
 
  detectFlashVer:function (reqMajorVer, reqMinorVer, reqRevision) {
    var reqVer = parseFloat(reqMajorVer + "." + reqRevision);
    for (var i=25;i>0;i--) { 
      if (this._isIE && this._isWin && !this._isOpera) var versionStr = VBgetSwfVer(i);
      else var versionStr = this.getSwfVer(i);
      if (versionStr == -1 ) return false;
      else if (versionStr != 0) {
        if(this._isIE && this._isWin && !this._isOpera) {
          var tempArray         = versionStr.split(" ");
          var tempString        = tempArray[1];
          var versionArray      = tempString .split(",");      
        } else var versionArray = versionStr.split(".");
        //
        var versionMajor      = versionArray[0];
        var versionMinor      = versionArray[1];
        var versionRevision   = versionArray[2];
       
        var versionString     = versionMajor + "." + versionRevision;   // 7.0r24 == 7.24
        var versionNum        = parseFloat(versionString);
            // è la versione maggiore >= versione maggiore richiesta è la versione minore >= versione minore richiesta
        if ( (versionMajor > reqMajorVer) && (versionNum >= reqVer) ) return true;
        else return ((versionNum >= reqVer && versionMinor >= reqMinorVer) ? true : false );
      }
    }
    return (reqVer ? false : 0.0);
  },
 
  // TO DO
  insertFlash: function(n,w,h) {
    if( this.detectFlashVer(8,0,0) ) {
      n += ".swf";
      document.write( '<object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=7,0,29,0" width="'+w+'" height="'+h+'">\n' );
      document.write( '<param name="movie" value="'+n+'" />\n');
      document.write( '<param name="quality" value="auto" />\n' );
      document.write( '<embed src="'+n+'" width="'+w+'" height="'+h+'" quality="auto" pluginspage="http://www.macromedia.com/go/getflashplayer" type="application/x-shockwave-flash"></embed>\n' );
      document.write( '</object>\n');
    } else document.write( '<a id="flash_alternate" target="_blank" href="http://www.adobe.com/go/getflashplayer"></a>' );
  }
};

//-->

Come al solito, Internet Explorer (7) si differenzia e vuole un codice appositamente strutturato in VBScript:

[vb]

[/vb]

Salviamo questi due file (df.js e df.vbs nella cartella js) e includiamoli nella nostra pagina (index.html, index.php o default.html, ecc…) all’interno del TAG HEAD.

1
2
<script language="javascript1.2" type="text/javascript" src="js/df.js"></script>
<script language="VBScript" type="text/vbscript" src="js/df.vbs"></script>

Ora abbiamo tutto il necessario e possiamo spostarci nella pagina che conterrà l’oggetto Flash. Posizionatevi nel punto dove Flash sarà visualizzato e inserite il seguente codice:

1
<script language="javascript1.2" type="text/javascript">df.insertFlash("flash/splash","900","122");</script>

Nell’esempio abbiamo assunto che esista un file splash.swf nella cartella flash! Notate che non è necessario inserire l’estensione swf. I due numeri 900 e 122 sono le dimensioni.

Ancora meglio sarebbe supportare il caso – remoto – dove Javascript è stato disabilitato. In questa circostanza potete scegliere di procedere in due modi:

1. Inseire direttamente in codice OBJECT/EMBED
2. Notificare che Javascript è disabilitato

Nel primo caso perdiamo il controllo sulla presenza di Flash ed Explorer richiederà di attivare il controllo ActiveX. Tuttavia il filmato sarà visibile, se Flash è installato.

Nel secondo caso possiamo mostrare un’immagine e/o notoficare che con Javascript spento non è possibile verificare la presenza del Plug-in Adobe Flash. Ad esempio, scegliendo la soluzione numero 1:

1
2
3
4
5
6
7
8
9
10
<div id="claim">
    <script language="javascript1.2" type="text/javascript">df.insertFlash("flash/splash","900","122");</script>
  <noscript>
    <object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=7,0,19,0" width="900" height="122">
            <param name="movie" value="flash/splash.swf" />
            <param name="quality" value="high" />
            <embed src="flash/splash.swf" quality="high" pluginspage="http://www.macromedia.com/go/getflashplayer" type="application/x-shockwave-flash" width="900" height="122"></embed>
    </object>
  </noscript>
</div>

Rilevare Flash e gestire le numerose alternative, come spiegato su Flash detect: come rilevare Flash, non è proprio comodissimo, speriamo almeno che la cosa non andrà a peggiorare con il tempo.

Continua...

HTML dinamico con Javascript

Scrivere codice HTML dinamicamente all’interno di una pagina è possibile ed utile. Il modo più diretto e conosciuto è quello di utilizzare documenti.write() o un contenitore DIV predisposto ad accettare codice inserito tramite innerHTML. In alternativa è possibile agganciarsi ad un TAG esistente ed utilizzare il DOM per aggiungere o rimuovere elementi all’interno della pagina. Ad esempio immmaginiamo di voler caricare un nuovo file Javascript senza utilizzare scripting lato server e quindi il ricaricamento della pagina. La funzioni qui sotto, ad esempio, aggiunge un file Javascript alla vostra pagina, passato come parametro (comprensivo di path).

1
2
3
4
5
6
function addScripting(s) {
 var scriptNode = document.createElement('script');
 document.getElementsByTagName("head")[0].appendChild(scriptNode);
 scriptNode.language='javascript';
 scriptNode.src=s;
}

Similmente è possibile aggiungere un foglio di stile alla nostra pagina, indicato dalla variabile cssfile:

1
2
3
4
5
var cssNode = document.createElement('link');
cssNode.setAttribute('rel', 'stylesheet');
cssNode.setAttribute('type', 'text/css');
cssNode.setAttribute('href', cssfile );
document.getElementsByTagName('head')[0].appendChild(cssNode);

Continua...

Flash detect: come rilevare Flash

Come si può determinare se un browser ha installata la versione corretta del Plugin Adobe Flash? Per fare questo esistono – notoriamente – 5 tecniche:

  • Affidarsi alla caratteristica auto-installante dei TAG OBJECT ed EMBED
  • Utilizzare uno script (Javascript e/o VBScript) appositamente fornito da Adobe
  • Utilizzare un artifizio con un solo filmato Flash
  • Non fare nulla ;)
  • Far scegliere all’utente

Continua...

Ajax senza HTTPRequest

Come molti sviluppatori Web sanno, prima dell’avvento dell’oggetto XMLHttpRequest, il problema del ricaricamento di una pagina Web veniva risolto con la tecnica dei FRAME o IFRAME nascosti. Questo artifizio ha permesso per molti hanni di risolvere alcune problematiche di interfaccia altrimenti irrisolvibili. Un vantaggio nell’uso dei FRAME nascosti, tra l’altro, era la possibilità di mantenere l’HISTORY del browser! Cosa che l’oggetto XMLHttpRequest non permette.

Oltre a tecniche HTML che ricorrono a FRAME o IFRAME nascosti, esiste la possibilità di usare Flash come sub-canale di comunicazione tra la pagina e il Server. Alcune esperienze in tale direzione sono tuttora in sviluppo (vedi ad esempio Fjax). L’idea è quella di “nascondere” un filmato Flash all’interno della pagina HTML (come accadeva con i FRAME) e comunicare con esso tramite Javascript (o VBScript per il solo ambiente Microsoft).

Tuttavia questa tecnica nascoste una serie di insidie. Prima di tutto costringe l’utente finale ad installare il PlugIn di Flash, e quindi non rappresenta una soluzione HTML (pura) pulita. Inoltre richiede comunque l’uso spinto di Javascript come interfaccia tra Flash e la pagina, quindi tanto vale la pena usare l’oggetto XMLHttpRequest. Quando poi si inizia a scrivere un framework in ActionScript viene voglia di realizzare tutto in Flash. Ecco che la variante all’oggetto XMLHttpRequest comincia ad avere poco senso.
In definitiva se non si vuole usare l’oggetto XMLHttpRequest, conviene affidarsi all’ormai consolidata tecnica dei FRAME nascosti. Addirittura c’è chi usa proprio una tecnica mista: XMLHttpRequest + IFRAME!

Tuttavia, oramai, Ajax (nella forma dell’oggetto XMLHttpRequest) ha riscosso un così grande successo che in futuro l’oggetto XMLHttpRequest verrà sia supportato che migliorato dai produttori di browser (come Microsoft, Mozilla, Opera, ecc…). In pratica XMLHttpRequest diventerà un componente di default (come accade già in FireFox) all’interno del browser, raggiungibile via Javascript! Quindi perchè non usarlo?

Continua...

Protopage v3: qualcosa di nuovo all’orizzonte

Su Ajaxan.com è comparso un articolo interessante su un’esperienza londinese davvero simpatica. Protopage è un piccolo sistema operativo dedicato allo condivisione. Il motore dell’ambiente è ben scritto e l’interfaccia risulta estremamente facile da usare. Questo è sicuramente un bell’esempio di come il Web sta evolvendo. Tuttavia rimangono ancora insidie di compatibilità, vedi ad esempio Explorer 7, ma la strada sembra densa di sorprese.

Continua...

Usare Microsoft Internet Explorer 6 e 7 contemporaneamente

Sul Blog di IE7 è uscito un articolo (IE6 and IE7 Running on a Single Machine) che potrebbe migliorare le notti insonni di molti sviluppatori Web! Microsoft si è resa conto (fortunatamente) che l’avvento di Internet Explorer 7 causa, di fatto, l’abbandono della precedente versione 6. Infatti non è possibile far convivere entrambi i browser sulla stessa macchina. Per gli utenti finali questo non è un problema, ma per gli sviluppatori Web che vogliono mantenere una compatibilità con la versione 6 è un vero e proprio disastro. La soluzione, proposta su vari altri Blog, è quella di utilizzare una macchina virtuale, come VMWare o Virtual PC della setssa Microsoft.

L’indicazione è quella di installare sulla macchina reale principale l’ultima release del browser, la versione 7. Dotarsi poi di un player o di un software di virtualizzazione così da far girare virtualmente in questo ambiente separato la vecchia versione 6 di explorer.

NOTA BENE:

Microsoft mette a disposizione anche un file con un ambiente già virtualizzato, scaricabile all’indirizzo:
http://go.microsoft.com/fwlink/?LinkId=70868

Questo file si traduce in un .vhd file, non utilizzabile con VMWare. Inoltre chi possiede un Windows XP Home – come vedrà – non potrà utilizzare Virtual PC 2004 di Microsoft che richiede almeno Windows XP Professional (sul sito questa informazione è indicata davvero male!).

Tuttavia, quasi a voler essere un pesce d’aprile, il 1 Aprile 2007 questa macchina virtuale non sarà più utilizzabile! Nel Blog viene comunque sottolineato che il team di sviluppo spera di poter rilasciare in futuro ulteriori aggiornamenti di queste macchine virtuali preconfezionate.

Morale, questa soluzione è comunque approssimativa e non soddisfa davvero tutti! Andrebbe permesso l’uso di VMWare e quindi rilasciata una macchina virtuale compatibile con questo software, palesemente concorrente a Virtual PC 2004 – da poco rilasciato free da Microsoft ;) – o travare un modo per convertire il file .vhd di Microsoft in un file accettabile per VMWare. Se avete suggerimenti…

Continua...

Google sotto accusa: le responsabilità della Net TV

Nell’era della diffusione in massa delle informazioni (Video, audio, testuali, ecc…) c’è chi attacca senza pensare, senza rendersi conto di quello che sta davvero accadendo. L’associazione italiana Vivi Down, giustamente risentita – come tutte le persone civili – dalla “messa in onda” del filmato girato in una scuola torinese dove alcuni alunni maltrattano e umiliano un loro compagno down, denuncia Google Video per aver omesso una necessaria e dovuta funzione di controllo.

Ad oggi è impensabile verificare tutti i contenuti video inoltrati liberamente nella rete, proprio per le sue caratteristiche di “tempo reale” e “globalità”. Risulta invece strano l’attacco dell’associazione e dei PM italiani nei confronti Goggle, ultimo tassello di un degrado che con la rete Internet non ha nulla a che fare.
I ragazzi della scuola torinese hanno fatto quello che hanno fatto non certo per colpa di Google. Anzi! Grazie a Google, almeno, sappiamo chi sono, come hanno operato e abbiamo potuto riconoscerli e punirli. I ragazzi, la professoressa assente e gli altri alunni, devono solo vergongnarsi e essere perseguiti con tutti i mezzi messi a disposizione dalla società, dall’istituzione scolastica e dalla giustizia. In tutta questa faccenda Google non c’entra davvero nulla. Il video, girato con un telefonico (denuciamio quindi anche il gestore telefonico?!…) sarebbe potuto essere diffuso in tanti altri modi.

Non dobbiamo spendere tempo ed energie verso un colpevole “inventato”. La verità è che la vera colpa è nell’educazione che la società, tramite la scuola e la famiglia, non riesce più a dare ai nostri figli. La vera oscenità del video torinese è la professoressa che gira lo sguardo e esce, quello è il nocciolo del problema! Se il “controllore” evade i suoi doveri è ovvio che a cascata ci rimettiamo tutti. Se la professoressa avesse fatto il suo dovere, non avremmo saputo nulla.

Quanti atti di prepotenza vengono perpetuati ai danni dei più deboli continuamente?

Non è certo una novità! Sono gli organi di controllo locale a svolgere il lavoro più importante e fondamentale. Questo è valido in generale dove gli organi di controllo sono i professori e i presidi nella scuola, i genitori all’interno della famiglia, le forze dell’ordine nelle città! E via discorrendo…

Sono loro che devono avere la nostra attenzione e il nostro ascolto quando le cose non procedono nel modo giusto. Dovremmo, quindi, cercare di capire cos’è che non ha funzionato nel meccanismo di controllo della scuola torinese invece di attaccare Google Video.

Continua...



Stop SOPA