Newsgroup: it.comp.lang.javascript
Titolo: verificare presenza e versione del plugi flash

Salve a tutti.
Sto cercando un modo multi-browser per verificare la presenza e la 
versione del plugin Flash di Adobe/Macromedia.
Mi sapreste dare un consiglio in merito ?
Grazie
Ciao

 Ciao
prego, ciao.

raenkrus ha scritto:

mi quoto per aggiungere questo:
http://www.howtocreate.co.uk/wrongWithIE/?chapter=navigator.plugins

 versione del plugin Flash di Adobe/Macromedia.
function flash_is_installed( )
{
   var res = false;
   if( typeof window.ActiveXObject != 'undefined' )
   {
      try
      {
         res = new ActiveXObject( 'ShockWaveFlash.ShockWaveFlash' );
         res = true;
      }
      catch( e )
      {
         res = false;
      }
   }
   else if( navigator && navigator.mimeTypes &&
      navigator.mimeTypes[ 'application/x-shockwave-flash' ] )
   {
      if(
navigator.mimeTypes['application/x-shockwave-flash'].enabledPlugin )
         res = true;
   }
   else if( navigator && navigator.plugins &&
    navigator.plugins[ 'Shockwave Flash' ] )
   {
      res = true;
   }
   return res;
}

       {
Se si tratta di un applicazione va bene, ma nel caso di siti web sarebbe
preferibile evitare l'uso di try/catch in questo modo, perché i browser che
non supportano tale statement generano errore di sintassi, mandandoti in
errore tutto lo script.
Inoltre, quando si tratta di object checking, generalmente dovresti prima
controllare le proprietà più standard; e poi quelle meno. Quindi il check su
window.ActiveXObject non dovrebbe risultare in testa.
Ti capisco, perché è capitato anche a me di fare la medesima cosa (viene
istintivo preoccuparsi "prima" dei "problemi"... e in tal caso il problema è
"ActiveXObject"), ad esempio quando buttai giù il codice sul NG di
getXmlHttpRequest; che poi corressi le volte successive.
Premesso che io non sono un "flashista" (oddio, sembra "fascista" detto da
qualcuno con un difetto di pronuncia :P ), e che non mi occupo di questo
genere di cose, ho buttato giù al volo un'idea alternativa per IE (>4, ma
volendo è adattabile anche a quest'ultimo).
Ho visto che generalmente si utilizza il blocco try/catch o codice VBScript,
con un ciclo per recuperare la versione dell'ActiveXObject. Io ho pensato a
questo approccio alternativo:
function getIEFlashVersion(){
	var obj = document.createElement("object"),
		ver = -1;
 
	obj.setAttribute("classid","clsid:D27CDB6E-AE6D-11cf-96B8-444553540000");
 
	if (typeof obj.FlashVersion!="undefined"){
		ver = obj.FlashVersion()>>16;
		obj = null;
	}	
	return ver;
}
window.onload=function(){
	var flashver;
	if ( ( flashver = getIEFlashVersion() ) >-1 )
		alert("Flash "+flashver+" installato.");
	else
		alert("Nessun Plugin Flash riconosciuto.")
}
Non mi pare di averlo visto molto a giro, ed è probabile che in tal caso
possa avere dei difetti di utilizzo pratico che, in quanto non usando Flash,
non mi sia accorto.
Quindi se c'è qualcuno che è pratico di questo genere di cose, e volesse
buttargli un occhio...
Ovviamente va integrato con i codici già esistenti per i browser che
supportano mimeTypes/plugins, cosa che farò se risulterà un codice valido.
-- 
~ "When you have eliminated the impossible, whatever remains,
however improbable, must be the truth." (S.H.)

 	}	
"obj = null" va fuori dall'if, pardon:
	if (typeof obj.FlashVersion!="undefined"){
		ver = obj.FlashVersion()>>16;
	}
	obj = null;
-- 


 window.ActiveXObject non dovrebbe risultare in testa.
ok, giusto
allora, ispirandomi a:
function getXmlHttpRequest( )
{
   var xmlhttp = null;
   if( typeof window.XMLHttpRequest != "undefined" )
   {
      xmlhttp = new XMLHttpRequest( );
   }
   else if( typeof window.ActiveXObject != "undefined" )
   {
      /*@cc_on
      @if( @_win32 && @_jscript_version >= 4 )
      {
         try
         {
            xmlhttp = new ActiveXObject( "Msxml2.XMLHTTP" );
         }
         catch( e )
         {
            try
            {
               xmlhttp = new ActiveXObject( "Microsoft.XMLHTTP" );
            }
            catch( E )
            {
               xmlhttp = null;
            }
         }
      }
      @end
      @*/
   }
   return xmlhttp;
}
di cui tu dovresti rivendicarne parziale paternita'
si potrebbe fare cosi':
function flash_is_installed( )
{
   var res = false;
   if( navigator && navigator.mimeTypes &&
      navigator.mimeTypes['application/x-shockwave-flash' ] )
   {
if(navigator.mimeTypes['application/x-shockwave-flash'].enabledPlugin)
         res = true;
   }
   else if( navigator && navigator.plugins &&
      navigator.plugins[ 'Shockwave Flash' ] )
   {
      res = true;
   }
   else if( typeof window.ActiveXObject != 'undefined' )
   {
      /*@cc_on
      @if( @_win32 && @_jscript_version >= 4 )
      {
         try
         {
            res = new ActiveXObject( 'ShockWaveFlash.ShockWaveFlash' );
         }
         catch( e )
         {
            res = false;
         }
      }
      @end
      @*/
   }
   return res;
}

    }
Del tutto inutile. IE5/Mac dovrebbe supportare mimeTypes/plugins, quindi una
volta spostato come primo object checking quest'ultimi come ti ho suggerito,
non passerà a fare il check per window.ActiveXObject (cosa che invece
avrebbe fatto nel tuo codice perché era in testa).
Inoltre con l'approccio alternativo, che hai bellamente saltato :), puoi
benissimo fare a meno del try/catch e quindi dei commenti condizionali.
Ovviamente prima di invocare la funzione bisognerebbe accertarsi del
supporto di document.createElement, ma è un semplice controllo che può
essere fatto nella funzione cross-browser, non uno statement come try/catch.


 essere fatto nella funzione cross-browser, non uno statement come try/catch.
ok

>> si potrebbe fare cosi':
ah, no, forse ho capito cosa intendevi, una cosa tipo:
function getXmlHttpRequest( )
{
   var xmlhttp = null;
   if( typeof window.XMLHttpRequest != "undefined" )
   {
      xmlhttp = new XMLHttpRequest( );
   }
   else if( typeof window.ActiveXObject != "undefined" )
   {
      /*@cc_on
      @if( @_win32 )
      {
         xmlhttp = new ActiveXObject( "Msxml2.XMLHTTP" );
         if( ! xmlhttp )
            xmlhttp = new ActiveXObject( "Microsoft.XMLHTTP" );
      }
      @end
      @*/
   }
   return xmlhttp;
}

 ma perche' l'"approccio alternativo" e' ancora una beta :P
E che c'entra? L'hai provato? :)


 E che c'entra? L'hai provato? :)
Nota: sono appena tornato dalla pausa pranzo e mi sono venute in mente un
paio di migliore da apportare, appena ho un attimo pubblico il codice.


 paio di migliore da apportare, appena ho un attimo pubblico il codice.
Amico mio, tu nella pausa pranzo pensi al plugin detection? Sei in quai
seri, allora :)
-- 
Nando [?]
Apostolo della Prova

 paio di migliore da apportare, appena ho un attimo pubblico il codice.
Mi ero messo a fare tutta una serie di ragionamenti, ma poi mi son detto che
il gioco non valeva la candela... Anche perché, comunque, io non uso molto
Flash. E sono altresì convinto, che il suo detect lascia il tempo che trova.
Però, magari, a qualcuno può risultare effettivamente utile.
Questo è al momento il risultato della funzione crossbrowser. La cosa a mio
vedere interessante è che non utilizza mezzi proprietari MS per fare il
detect su IE (fin'ora ne ho visti fatti in VBS, con la compilazione
condizionale o ActiveXObject), né try/catch.
Tant'è che idealmente, l'ultima parte potrebbe funzionare anche su Gecko
(dico "idealmente" perché da una rapida prova ho notato che su Gecko dovrei
appendere al DOM il nodo creato in memoria e dare al browser il tempo di
capire di cosa si tratta, prima di invocare il metodo FlashVersion()... non
mi è sembrato il caso)
La funzione ritorna un intero che identifica la versione di Flash (ma va' :)
): nel caso di -1 non c'è Flash installato, nel caso di 0 non è possibile
recuperarne la versione.
Ripeto, dato che non sono un grande utilizzatore di Flash, tale funzione può
essere tutt'altro che perfetta. Nel caso, penso che si vedrà con l'uso.
function getFlashVersion(){
	var obj, ver = -1;
	if (navigator.plugins && navigator.plugins.length > 0){
		if ( (obj = navigator.plugins["Shockwave Flash"]) ){
			ver = 0;
			if (obj.description){
				ver = parseInt(obj.description.substr(obj.name.length),10);
			}
		}else if (navigator.plugins["Shockwave Flash 2.0"]){
			ver = 2;
		}
	}else if (navigator.mimeTypes && navigator.mimeTypes.length > 0 ){
		if ( (obj = navigator.mimeTypes["application/x-shockwave-flash"]) &&
obj.enabledPlugin ){
			ver = 0;
		}
	}else if (document.createElement){
		obj = document.createElement("object");
 
		if (obj.setAttribute){
			obj.setAttribute("type","application/x-shockwave-flash");
			if (typeof obj.FlashVersion!="undefined")
				ver = obj.FlashVersion()>>16;
		}
		obj = null;
	}
	return ver;
}


 seri, allora :)
Non rammenti...?
Stai parlando con uno che quando in ascensore sentì la ragazza accanto che
tirava fuori il cellulare, si è voltato per capire se era un modello sul
quale poteva sviluppare in J2ME. Mica per vedere la ragazza.
:)


 :)
Ma non ci credo neanche se lo vedo... a meno che non si trattasse di uno
scorfano :-]


 a meno che non si trattasse di uno scorfano :-]
Non ci ho fatto caso, il bello è quello. ^_^; è anche vero che era mattina
presto, stavo andando a lavoro, quindi non ero totalmente "presente"
ancora... (la qual cosa potrebbe anche essere vista come un'aggravante,
però: significa che istintivamente il mio inconscio è andato a pensare a
J2ME..)


 J2ME..)
Eh sì, la situazione è gravissima, urge vacanza di almeno 2 mesi attorniato
da belle figliuole... la passione va bene, ma se diventa alienazione dal
reale (e soprattutto dal fascino femminile) allora è patologica :)


 reale (e soprattutto dal fascino femminile) allora è patologica :)
E' che io vado a periodi. Ci sono delle volte che sono una "macchina" in un
senso; e delle altre che sono una "macchina" in un altro. :P


 senso; e delle altre che sono una "macchina" in un altro. :P
Sborone :)


 Sborone :)
Sborone è quando millanti qualcosa che non corrisponde a realtà :)
Altrimenti è semplice constatazione di un dato di fatto.
"La modestia è una qualità decisamente sopravvalutata" (C.X.)


 Altrimenti è semplice constatazione di un dato di fatto.
*SBORONE!*  :-)
-- 
"That until there is no longer first class
And second class citizens of any nation
Until the colour of a man's skin
Is of no more significance than the colour of his eyes
Me say war"
B.M.

 *SBORONE!*  :-)
ghghgh..


 Altrimenti è semplice constatazione di un dato di fatto.
Errato !
Sborone e' uno che vuole essere esibizionista esaltandosi all'estremo 
delle sue capacita' per fare impressione (bella figura).
Poi spesso capita che chi vuole fare lo sborone tenti cose al di la' 
delle proprie capacita' e si faccia pure male :)
Esmepio di sborone:
- Uno che fa l'impennata sui viali cittadini, con l'intendo proprio di 
farsi vedere
- Uno che al mare fa tuffi esagerati per farsi vedere
- Uno che gira con lo stereo della macchina a tutto spiano per farsi vedere
- Uno che racconta con molta enfasi un'anedotto
- Uno dopo un goal stratosferico puo' dire: "sono stato proprio sborone :)"
In ognuno di questi casi, sia che la cosa vada a buon esito o che vada 
male, l'intento e' sempre quello di fare lo sborone.
Nel caso in cui, la cosa vada male allora sei uno "sfighe'" (sfigato) :)
( diciamo che puo' essere un po' visto positivamente e un po' 
negativamente, quindi si adatta alle seguenti traduzioni:
- Figo ( quando fai una sboronata bella e di successo )
- Sfigato ( quando tenti una sboronata, ma ti va male )
- Tamarro ( quando fai lo sborone mettendo in mostra delle cazzate (tipo 
lo stereo della macchina a tutto spiano) )
-  ...
Insomma, come molti termini dialettali, si presta molto ad essere 
interpretato in vari modo a seconda del contesto :)
Sborone arriva dal Bolognese, e poi diventato di moda in tutt'Italia con 
"Oriano Ferrari" il meccanico della Ferrari di Zelig ( Marco Dalla Noce ).
Ciao e grazie a tutti per l'aiuto !

 "Oriano Ferrari" il meccanico della Ferrari di Zelig ( Marco Dalla Noce ).
In verità io la terminologia l'ho imparata in Emilia Romagna quando ho
vissuto a Rimini però, non a Bologna; prima che arrivasse Zelig a divulgarne
l'uso. Ho sempre pensato fosse un termine Romagnolo in generis, non Riminese
o Bolognese. :)


 Bada che stavamo scherzando... :)
Niente storie: sei uno sborone punto e basta :)


 Niente storie: sei uno sborone punto e basta :)
Puntualizziamo: Come ho detto, è una semplice constatazione di fatto. :)
Se poi voi mi vedete sborone.. ehò, problema vostro, mica mio. :D


 o Bolognese. :)
Si', ma mi raccomando: da noi si dice "sburòn", pronunciando una quasi 
impercettibile "u" dopo la "o".
La "s" come sapete.

 La "s" come sapete.
Aaaah!!! Egli è vivo! :D
Bentornato. E cmq si, ovvio che la pronuncia sia diversa.. ma il termine è
quello. :)


 quello. :)
Vabbe', per ora sono un lettore passivo.
Il termine e' quello, e ormai via Zelig mi hanno definitivamente 
sdoganato anche "invornito".
Questo piu' propriamente riminese credo, neanche romagnolo, ma anche a 
Bologna lo capiscono.
E in italiano, davvero, mancava.
Ad maiora.

 }
un problema che ci potrebbe essere e' che con questo approccio non si puo'
chiamare questa funzione se non dopo il caricamento della pagina...
cosa ne dici di una cosa cosi'?
function getFlashVersion( )
{
   var obj, ver = -1;
   if( navigator.plugins && navigator.plugins.length > 0 )
   {
      for( var i in navigator.plugins )
      {
         obj = navigator.plugins[i];
         if( 
obj.name
 && ! obj.name.indexOf( 'Shockwave Flash' ) )
         {
            ver = 0;
            if( obj.description )
               ver = parseInt( obj.description.substr( obj.name.length ) );
            break;
         }
      }
   }
   else if( navigator.mimeTypes && navigator.mimeTypes.length > 0 )
   {
      obj = navigator.mimeTypes['application/x-shockwave-flash'];
      if( obj && obj.enabledPlugin )
         ver = 0;
   }
   else if( document.createElement &&
	( obj = document.createElement( 'object' ) ) != null )
   {
      if( obj.setAttribute )
      {
         obj.setAttribute( 'type', 'application/x-shockwave-flash' );
         if( typeof obj.FlashVersion != 'undefined' )
            ver = obj.FlashVersion( ) >> 16;
      }
   }
   else if( typeof window.ActiveXObject != 'undefined' )
   {
      /*@cc_on
      @if( @_win32 )
      {
         obj = new ActiveXObject( 'ShockWaveFlash.ShockWaveFlash' );
         if( obj && typeof obj.FlashVersion != 'undefined' )
            ver = obj.FlashVersion( ) >> 16;
      }
      @end
      @*/
   }
   return ver;
}
dove ho leggermente modificato la prima parte
e dove eventualmente di puo' "risporcare" la funzione con il quarto elseif
cio' avrebbe in teoria dato la compatibilita' con IE4 che pero' non
gradisce typeof obj.FlashVersion != 'undefined' (andando in errore) ma
restituirebbe correttamente il valore obj.FlashVersion( )...
boh
sara' colpa di far convivere i vari IE insieme...

 sara' colpa di far convivere i vari IE insieme...
Ah, stai usando IE4 come "IE" Se fa parte di quelle installazioni "stand
alone" lascia perdere. Come più volte scritto, non sono affidabili per il
testing reale. Solo, eventualmente, per il CSS engine. Condividono troppe
cose, in primis lo script engine che è separato dal browser.
Inoltre, se questa è la parte relativa a IE4:
  else if( typeof window.ActiveXObject != 'undefined' )
   {
      /*@cc_on
      @if( @_win32 )
      {
         obj = new ActiveXObject( 'ShockWaveFlash.ShockWaveFlash' );
         if( obj && typeof obj.FlashVersion != 'undefined' )
            ver = obj.FlashVersion( ) >> 16;
      }
      @end
      @*/
   }
Mi sa che è sbagliata. (Compito per casa: perché? :) )


 Ah, stai usando IE4 come "IE" Se fa parte di quelle installazioni "stand
Era "IE parallelo".


 Mi sa che è sbagliata. (Compito per casa: perché? :) )
Mmmm
dovrei andare un po' in msdn mi sa'...
un aiutino :)

ZER0 ha scritto:

Bologna e' in Emilia non in Romagna ... precisiamolo ;)
Quindi per quanto dici, il termine risulterebbe essere di uso regionale, 
quindi emiliano-romagnolo.
Ciao
Ciao

Andrea Scartabelli ha scritto:

A dire il vero, quel termine a bologna, non solo e' capito, ma anche 
usato non poco.
Penso che certi modi di dire siano a piu' ampio raggio che non la sfera 
locale, si sconfina quindi penso nel regionale :)
Ciao

 un aiutino :)
Che non hai assolutamente risolto il problema del detect di flash. Se si
potesse fare così, non ti pare che sarebbe tranquillamente applicabile anche
alle altre casistiche e versioni di IE, senza tirare in ballo tutto
quell'ambaradan? :)


 senza tirare in ballo tutto quell'ambaradan? :)
Non ho capito :(
Riformulo bene la domanda:
con il seguente codice si dovrebbe riuscire a determinare la presenza del
plag-in di Flash e nel caso l'eventuale versione:
if( typeof window.ActiveXObject != 'undefined' )
{
	/*@cc_on
	@if( @_win32 )
	{
		if( obj = new ActiveXObject( 'ShockWaveFlash.ShockWaveFlash' ) )
		{
			ver = 0;
			if( typeof obj.FlashVersion != 'undefined' )
				ver = obj.FlashVersion( ) >> 16;
		}
	}
	@end
	@*/
}
con IE6 in effetti sembra funzionare...
La domanda e': perche' non dovrebbe andare con IE4?

 La domanda e': perche' non dovrebbe andare con IE4?
Non va neppure con IE6, se č per questo. O con IE5, IE5.5 e presumo anche
IE7.
Perň vorrei che tu ci arrivassi da solo. Mi dai l'impressione (vedasi anche
il discorso sulle varie versioni di MSXML) che spesso tu adotti soluzioni
scritte da altri, senza perň capirle e studiarle nel dettaglio. Arrivando
poi, a implementare qualcosa che senza aver capito del tutto il perché. Con
il rischio di arrivare a questo genere di risultati.


 il rischio di arrivare a questo genere di risultati.
In effetti, non posso negarlo :(

> E allora cerca di capire cosa c'è che non va. :)
credo di aver capito:
obj = new ActiveXObject( 'ShockWaveFlash.ShockWaveFlash' )
manda lo script in errore nel caso non sia installato il plug-in (e in
generale quando non esiste il corrispondente ActiveX)
quindi bisognerebbe reintrodurre try & cache
qundi andrebbe in errore con IE4
allora si potrebbe mettere il controllo della versione su JS (>= 4)
pero' cosi' si escude IE4
giusto?
Cambiando disorso:
mi sembra che ci siano dei problemi con la creazione al volo di un filmato
flash con IE anche se si specifica un file esistente, ho fatto delle prove
e non sono riuscito nemmeno a farlo visualizzare
var obj = document.createElement( 'object' );
obj.setAttribute( 'type', 'application/x-shockwave-flash' );
obj.setAttribute( 'data', 'movie.swf' );
obj.setAttribute( 'width', '40' );
obj.setAttribute( 'height', '40' );
document.body.appendChild( obj );
var par = document.createElement( 'param' );
par.setAttribute( 'name', 'movie' );
par.setAttribute( 'value', 'images/loading.swf' );
sia
obj.appendChild( par );
che
obj.innerHTML = '<param name="movie" value="movie.swf" />
<param name="play" value="true" />';
non mi danno niente con IE (FF visualizza entrambi...)
forse sbaglio qualcosa...

 forse sbaglio qualcosa...
Immagino di si. Nel mio codice avevo utilizzato un certo approccio perché
era quello più "standard" compliant e raggiungeva (almeno apparentemente)
ugualmente lo scopo, in quanto trasformava il riferimento al tag object in
un'istanza dell'ActiveX di Flash.
Ma se si deve creare un tag object da aggiungere effettivamente al DOM, con
un filmato Flash, l'approccio cambia leggermente su IE (per via dei
comportamenti noti di questo browser).
Anche qui, sarebbe bene tu ci arrivassi da solo.
Tornando al discorso iniziale: Adesso sono in fase di "migrazione server" a
lavoro, quindi non ho un granché di tempo per mettermi a fare esperimenti.
A una prima occhiata, la soluzione più immediata al problema del tag object
con file swf rimane, come ho già detto, l'uso di un file esterno.
Ma sinceramente non mi piace questo genere di dipendenza. Inoltre penso che
a quel punto, il detect di Flash sia più intelligente farlo dal filmato
stesso.
Ma, ripeto, non sono un grande utilizzatore di Flash e solitamente non mi
metto a fare questo genere di accroccri.. generalmente, lascio che sia il
browser a occuparsi di tutto nativamente, eventualmente potendo un
disclaimer nella pagina in cui si avvisa l'utente della necessità di un dato
plugin.
La soluzione in JS l'avevo presa più per esercizio che per altro, e mi
piaceva il fatto che fosse realizzata senza uso di try/catch o compilatori
condizonali, ma semplicemente con gli standard del w3c; e che potesse
risultare utile a chi faceva uso di questo genere di codice. Pensavo che non
facesse richieste HTTP o si mettesse a ragionare sul filmato, fintanto che
questo non veniva impostato (tipo gli oggetti Image() con l'attributo src).
Appena avrò un po' più di tempo, magari tornerò sopra la cosa (anche se temo
che non si possa fare un granché, dato che è un comportamento che dipende
dall'ActiveX stesso di Flash, non tanto dal DOM, dal tag Object o altro)


 Già (errorucci a parte).
in 7 righe non uno ma piu' errori forse concettuali o forse altro..
ma sono un fenomeno :)
quando puoi mi dici quali sono le cavolate che ho detto 

 quando puoi mi dici quali sono le cavolate che ho detto
Ho detto "errorucci", intendevo quindi delle cose di lieve entità. Più che
altro, immagino, dovuti a distrazione e/o fretta. Altrimenti ti
"riprendevo". :)
- "try & cache" : try & catch
- "controllo della versione su JS (>= 4)" : la versione di JScript >= 5.
(Tralasciando quelli di grammatica, ma appunto qui di solito è colpa della
fretta)
Per quanto riguarda gli errori "concettuali", al limite ci sarebbe da
precisare che con un simile approccio non si esclude tanto IE4 in sé, quanto
lo script engine rilasciato con tale versione di browser; e quindi si vanno
ad escludere tutti gli IE4 "puri", per così dire.


 ad escludere tutti gli IE4 "puri", per così dire.
ammazza oh :|
giusto, qui e' probabile che ci ricadro'...
ma poi tante storie per IE4, pensa che a me quasi quasi manco mi interessa
IE5 :)
vabbe' sara' utile per altri :P
Grazie di tutto!

 locale, si sconfina quindi penso nel regionale :)
Non del tutto in questo caso: in Emilia, che io sappia, viene utilizzato 
con qualche variante solo tra Bologna e Ferrara.