Un petit billet ultra technique, ça faisait longtemps…
J’utilise beaucoup Prototype en ce moment, aussi bien dans mon travail de tous les jours que pour des petites applications que je réalise à titre personnel.
Comme je suis curieux, j’ai ouvert ce fameux fichier prototype.js et j’ai essayé de voir comment ça fonctionnait (en gros).
Dans les premières lignes du fichier, j’ai particulièrement apprécié la détection de navigateurs, simple mais efficace pour distinguer les quatre principales familles de navigateurs Web actuels :
Browser: {
IE: !!(window.attachEvent && !window.opera),
Opera: !!window.opera,
WebKit: navigator.userAgent.indexOf('AppleWebKit/') > -1,
Gecko: navigator.userAgent.indexOf('Gecko') > -1 && navigator.userAgent.indexOf('KHTML') == -1
},
Les labels des deux premières lignes sont évidents, on comprend qu’on essaye de détecter Internet Explorer (IE) et Opera. Concernant les deux suivants, il est utile de connaître un peu les moteurs de rendus des navigateurs (voir cette étude que j’avais réalisée l’an passé, jour pour jour) pour comprendre. WebKit/WebCore est le moteur de rendu de Safari et Gecko est le moteur de rendu de Firefox, mais aussi de Flock, Camino et SeaMonkey, pour ne citer qu’eux.
Ces quatres familles représentent actuellement et sans trop exagérer 99,9% des parts de marché des navigateurs. Inutile d’aller plus loin… Passons désormais au code proprement dit !
On remarque tout de suite un truc qui peut vous paraître bizarre : le double point d’exclamation. Comme vous le savez tous, un point d’exclamation en JavaScript (et dans de nombreux autres langages de programmation) sert à faire une négation, par exemple !true vaut false et !false vaut true. On pourrait donc penser qu’une double négation de quelque chose redonne forcément la valeur originale de ce quelque chose. C’est sans compter sur le fait que :
* !!false vaut false (évidemment)
* !!undefined vaut false
* !!null vaut false
* !!0 vaut false
* !!'' vaut false (chaîne vide)
Mais attention :
* !!'0' vaut true !
La double négation donnera toujours un booléen (true ou false) comme résultat et c’est ce que les développeurs de Prototype ont cherché ici.
La détection d’IE est assez subtile. On sait que window.attachEvent est une méthode propriétaire uniquement comprise par Internet Explorer (les navigateurs modernes ont eu la bonne idée d’implémenter la méthode addEventListener standardisée par le W3C). Enfin… presque… En effet, Opera l’interprète aussi ! Il fallait donc trouver une parade. Cette parade, c’est window.opera, un mystérieux objet qui n’existe que sur Opera et qui a pour vocation de faciliter le debugging sur ce navigateur ! Il est donc logique d’utiliser cet objet pour détecter si le navigateur est Opera ou pas.
Pour WebKit et Gecko, les développeurs de Prototype ont chipoté avec les User-Agent, faute d’avoir trouvé des méthodes ou objets ultra spécifiques à ces navigateurs. Pour WebKit, c’est simple, cette famille de navigateurs est la seule à contenir la chaîne de caractère AppleWebKit dans son User-Agent. Pour Gecko, on essaye d’extraire la chaîne de caractère Gecko et on aimerait que ce soit suffisant. Malheureusement, les navigateurs basé sur KHTML (qui est à la base de WebKit) possèdent aussi la chaîne de caractère Gecko dans leur User-Agent. On retire donc ce sous-ensemble pour parfaire la sélection !
Désormais, grâce à cette détection infaillible que réalise Prototype, vous pouvez utiliser sans crainte ce genre de code dans vos scripts :
if (Prototype.Browser.IE) {
// code pour Internet Explorer
}
else {
// code pour les autres navigateurs
}
C’est pas beau, mais croyez moi, c’est toujours bien d’avoir ça sous la main !
Voilà, c’était le grand retour des articles techniques sur ce blog. Alors, heureux ?
Comblé!
l’année 2008 commence bien 😉
LikeLike
Idem :).
Sympa le coup de la double négation ^^.
Sinon :
if (Prototype.Browser.IE) {
// code pour Internet Explorer
}
else {
// code pour les autres navigateurs
}
ça reflète tellement Microsoft contre le reste du monde ^^.
Bonne année en tous cas.
LikeLike
Super, même de grand matin c’était très agréable à lire 😉
LikeLike
Haaa, ça fait plaisir 🙂
Sinon, pour parler de l’article (un peu quand même), je ne suis pas du tout fan de la détection par l’User Agent 😐
A titre d’information dans mootools webkit est détecté par navigator.taintEnabled et gecko par document.getBoxObjectFor
LikeLike
Ah oui tiens, je vais soumettre ça à Sam Stephenson 😉
LikeLike
Tiens, vraiment super tout ça.. Dommage que je passe à Mootools pour mes prochains projets..
Devenu bien trop lourd prototype et scriptaculous!!
LikeLike
Je parlerai également de MooTools et de jQuery sur ce blog car je les utilise de temps en temps.
LikeLike
‘tain j’ai rien compris… sauf que dans un paragraphe tu n’intervertir pas “Point d’interrogation” et “point d’exclamation”?
On remarque tout de suite un truc qui peut vous paraître bizarre : le double point d’exclamation. Comme vous le savez tous, un point d’interrogation en JavaScript (et dans de nombreux autres langages de programmation) sert à faire une négation, par exemple !true vaut false et !false vaut true. On pourrait donc penser qu’une double négation de quelque chose redonne forcément la valeur originale de ce quelque chose. C’est sans compter sur le fait que
LikeLike
Ah bien vu Eric ! C’est corrigé !
LikeLike