778 lines
28 KiB
JavaScript
Executable File
778 lines
28 KiB
JavaScript
Executable File
/*! SWFObject v2.2 <http://code.google.com/p/swfobject/>
|
||
est publié sous la licence MIT <http://www.opensource.org/licenses/mit-license.php>
|
||
*/
|
||
|
||
var swfobject = function() {
|
||
|
||
var UNDEF = "undefined",
|
||
OBJECT = "object",
|
||
SHOCKWAVE_FLASH = "Shockwave Flash",
|
||
SHOCKWAVE_FLASH_AX = "ShockwaveFlash.ShockwaveFlash",
|
||
FLASH_MIME_TYPE = "application/x-shockwave-flash",
|
||
EXPRESS_INSTALL_ID = "SWFObjectExprInst",
|
||
ON_READY_STATE_CHANGE = "onreadystatechange",
|
||
|
||
win = window,
|
||
doc = document,
|
||
nav = navigator,
|
||
|
||
plugin = false,
|
||
domLoadFnArr = [main],
|
||
regObjArr = [],
|
||
objIdArr = [],
|
||
listenersArr = [],
|
||
storedAltContent,
|
||
storedAltContentId,
|
||
storedCallbackFn,
|
||
storedCallbackObj,
|
||
isDomLoaded = false,
|
||
isExpressInstallActive = false,
|
||
dynamicStylesheet,
|
||
dynamicStylesheetMedia,
|
||
autoHideShow = true,
|
||
|
||
/* Fonction centralisée pour la détection de la fonction de navigateur
|
||
- La détection de la chaîne de l'agent utilisateur n'est utilisée que lorsqu'aucune autre alternative n'est possible.
|
||
- Exécution directe pour obtenir des performances optimales
|
||
*/
|
||
ua = function() {
|
||
var w3cdom = typeof doc.getElementById != UNDEF && typeof doc.getElementsByTagName != UNDEF && typeof doc.createElement != UNDEF,
|
||
u = nav.userAgent.toLowerCase(),
|
||
p = nav.platform.toLowerCase(),
|
||
windows = p ? /win/.test(p) : /win/.test(u),
|
||
mac = p ? /mac/.test(p) : /mac/.test(u),
|
||
webkit = /webkit/.test(u) ? parseFloat(u.replace(/^.*webkit\/(\d+(\.\d+)?).*$/, "$1")) : false, // renvoie la version du webkit ou false s'il n'existe aucun webkit
|
||
ie = !+"\v1", // détection de fonction selon la solution proposée par Andrea Giammarchi : http://webreflection.blogspot.com/2009/01/32-bytes-to-know-if-your-browser-is-ie.html
|
||
playerVersion = [0,0,0],
|
||
d = null;
|
||
if (typeof nav.plugins != UNDEF && typeof nav.plugins[SHOCKWAVE_FLASH] == OBJECT) {
|
||
d = nav.plugins[SHOCKWAVE_FLASH].description;
|
||
if (d && !(typeof nav.mimeTypes != UNDEF && nav.mimeTypes[FLASH_MIME_TYPE] && !nav.mimeTypes[FLASH_MIME_TYPE].enabledPlugin)) { // navigator.mimeTypes["application/x-shockwave-flash"].enabledPlugin indique si les plug-ins sont activés ou désactivés dans Safari 3+
|
||
plugin = true;
|
||
ie = false; // détection de la fonction en cascade pour Internet Explorer
|
||
d = d.replace(/^.*\s+(\S+\s+\S+$)/, "$1");
|
||
playerVersion[0] = parseInt(d.replace(/^(.*)\..*$/, "$1"), 10);
|
||
playerVersion[1] = parseInt(d.replace(/^.*\.(.*)\s.*$/, "$1"), 10);
|
||
playerVersion[2] = /[a-zA-Z]/.test(d) ? parseInt(d.replace(/^.*[a-zA-Z]+(.*)$/, "$1"), 10) : 0;
|
||
}
|
||
}
|
||
else if (typeof win.ActiveXObject != UNDEF) {
|
||
try {
|
||
var a = new ActiveXObject(SHOCKWAVE_FLASH_AX);
|
||
if (a) { // "a" renverra null lors de la désactivation d'ActiveX
|
||
d = a.GetVariable("$version");
|
||
if (d) {
|
||
ie = true; // détection de la fonction en cascade pour Internet Explorer
|
||
d = d.split(" ")[1].split(",");
|
||
playerVersion = [parseInt(d[0], 10), parseInt(d[1], 10), parseInt(d[2], 10)];
|
||
}
|
||
}
|
||
}
|
||
catch(e) {}
|
||
}
|
||
return { w3:w3cdom, pv:playerVersion, wk:webkit, ie:ie, win:windows, mac:mac };
|
||
}(),
|
||
|
||
/* Evénement onDomLoad inter-navigateur
|
||
- Déclenchera un événement au chargement du DOM d'une page Web
|
||
- Alternative pour Internet Explorer selon la solution proposée par Diego Perini : http://javascript.nwbox.com/IEContentLoaded/
|
||
- L'événement onload standard sert de méthode de rappel
|
||
*/
|
||
onDomLoad = function() {
|
||
if (!ua.w3) { return; }
|
||
if ((typeof doc.readyState != UNDEF && doc.readyState == "complete") || (typeof doc.readyState == UNDEF && (doc.getElementsByTagName("body")[0] || doc.body))) { // la fonction est déclenchée après un événement onload, notamment lorsque le script est inséré de façon dynamique
|
||
callDomLoadFunctions();
|
||
}
|
||
if (!isDomLoaded) {
|
||
if (typeof doc.addEventListener != UNDEF) {
|
||
doc.addEventListener("DOMContentLoaded", callDomLoadFunctions, false);
|
||
}
|
||
if (ua.ie && ua.win) {
|
||
doc.attachEvent(ON_READY_STATE_CHANGE, function() {
|
||
if (doc.readyState == "complete") {
|
||
doc.detachEvent(ON_READY_STATE_CHANGE, arguments.callee);
|
||
callDomLoadFunctions();
|
||
}
|
||
});
|
||
if (win == top) { // s'il est en dehors d'une iframe
|
||
(function(){
|
||
if (isDomLoaded) { return; }
|
||
try {
|
||
doc.documentElement.doScroll("left");
|
||
}
|
||
catch(e) {
|
||
setTimeout(arguments.callee, 0);
|
||
return;
|
||
}
|
||
callDomLoadFunctions();
|
||
})();
|
||
}
|
||
}
|
||
if (ua.wk) {
|
||
(function(){
|
||
if (isDomLoaded) { return; }
|
||
if (!/loaded|complete/.test(doc.readyState)) {
|
||
setTimeout(arguments.callee, 0);
|
||
return;
|
||
}
|
||
callDomLoadFunctions();
|
||
})();
|
||
}
|
||
addLoadEvent(callDomLoadFunctions);
|
||
}
|
||
}();
|
||
|
||
function callDomLoadFunctions() {
|
||
if (isDomLoaded) { return; }
|
||
try { // vérifiez que nous pouvons réellement ajouter des éléments dans le DOM ou les supprimer ; nous ne voulons pas déclencher la fonction trop tôt
|
||
var t = doc.getElementsByTagName("body")[0].appendChild(createElement("span"));
|
||
t.parentNode.removeChild(t);
|
||
}
|
||
catch (e) { return; }
|
||
isDomLoaded = true;
|
||
var dl = domLoadFnArr.length;
|
||
for (var i = 0; i < dl; i++) {
|
||
domLoadFnArr[i]();
|
||
}
|
||
}
|
||
|
||
function addDomLoadEvent(fn) {
|
||
if (isDomLoaded) {
|
||
fn();
|
||
}
|
||
else {
|
||
domLoadFnArr[domLoadFnArr.length] = fn; // Array.push() est disponible uniquement dans IE5.5+
|
||
}
|
||
}
|
||
|
||
/* Evénement onload inter-navigateur
|
||
- Selon la solution proposée par James Edwards : http://brothercake.com/site/resources/scripts/onload/
|
||
- Déclenche un événement lorsqu'une page Web et tous les actifs qu'elle contient sont chargés
|
||
*/
|
||
function addLoadEvent(fn) {
|
||
if (typeof win.addEventListener != UNDEF) {
|
||
win.addEventListener("load", fn, false);
|
||
}
|
||
else if (typeof doc.addEventListener != UNDEF) {
|
||
doc.addEventListener("load", fn, false);
|
||
}
|
||
else if (typeof win.attachEvent != UNDEF) {
|
||
addListener(win, "onload", fn);
|
||
}
|
||
else if (typeof win.onload == "function") {
|
||
var fnOld = win.onload;
|
||
win.onload = function() {
|
||
fnOld();
|
||
fn();
|
||
};
|
||
}
|
||
else {
|
||
win.onload = fn;
|
||
}
|
||
}
|
||
|
||
/* Fonction principale
|
||
- Exécute de préférence l'événement onDomLoad, onload dans le cas contraire (comme méthode de rappel)
|
||
*/
|
||
function main() {
|
||
if (plugin) {
|
||
testPlayerVersion();
|
||
}
|
||
else {
|
||
matchVersions();
|
||
}
|
||
}
|
||
|
||
/* Détecte la version de Flash Player pour tous les navigateurs hormis Internet Explorer
|
||
- Il est plus précis de détecter la version du plug-in via l'élément de l'objet que d'utiliser la description de l'élément de la collection de plug-ins :
|
||
a. Permet de détecter le numéro de version et le numéro de publication
|
||
b. Permet d'éviter les descriptions inexactes de programmes d'installation corrompus fournis par Adobe
|
||
c. Permet d'éviter les descriptions inexactes de plusieurs entrées de Flash Player dans l'objet Array du plug-in provoquées par des importations de navigateur incorrectes
|
||
- L'un des inconvénients de cette méthode est qu'elle dépend de la disponibilité du DOM, alors que la collection de plug-ins est disponible immédiatement
|
||
*/
|
||
function testPlayerVersion() {
|
||
var b = doc.getElementsByTagName("body")[0];
|
||
var o = createElement(OBJECT);
|
||
o.setAttribute("type", FLASH_MIME_TYPE);
|
||
var t = b.appendChild(o);
|
||
if (t) {
|
||
var counter = 0;
|
||
(function(){
|
||
if (typeof t.GetVariable != UNDEF) {
|
||
var d = t.GetVariable("$version");
|
||
if (d) {
|
||
d = d.split(" ")[1].split(",");
|
||
ua.pv = [parseInt(d[0], 10), parseInt(d[1], 10), parseInt(d[2], 10)];
|
||
}
|
||
}
|
||
else if (counter < 10) {
|
||
counter++;
|
||
setTimeout(arguments.callee, 10);
|
||
return;
|
||
}
|
||
b.removeChild(o);
|
||
t = null;
|
||
matchVersions();
|
||
})();
|
||
}
|
||
else {
|
||
matchVersions();
|
||
}
|
||
}
|
||
|
||
/* Effectuez la correspondance des versions de Flash Player et du fichier SWF ; publication statique uniquement
|
||
*/
|
||
function matchVersions() {
|
||
var rl = regObjArr.length;
|
||
if (rl > 0) {
|
||
for (var i = 0; i < rl; i++) { // pour chaque élément d'objet enregistré
|
||
var id = regObjArr[i].id;
|
||
var cb = regObjArr[i].callbackFn;
|
||
var cbObj = {success:false, id:id};
|
||
if (ua.pv[0] > 0) {
|
||
var obj = getElementById(id);
|
||
if (obj) {
|
||
if (hasPlayerVersion(regObjArr[i].swfVersion) && !(ua.wk && ua.wk < 312)) { // version de Flash Player >= version SWF publiée : nous avons une correspondance !
|
||
setVisibility(id, true);
|
||
if (cb) {
|
||
cbObj.success = true;
|
||
cbObj.ref = getObjectById(id);
|
||
cb(cbObj);
|
||
}
|
||
}
|
||
else if (regObjArr[i].expressInstall && canExpressInstall()) { // affiche la boîte de dialogue d'installation d'Adobe Express si le programmateur de la page Web le permet et si l'affichage est pris en charge
|
||
var att = {};
|
||
att.data = regObjArr[i].expressInstall;
|
||
att.width = obj.getAttribute("width") || "0";
|
||
att.height = obj.getAttribute("height") || "0";
|
||
if (obj.getAttribute("class")) { att.styleclass = obj.getAttribute("class"); }
|
||
if (obj.getAttribute("align")) { att.align = obj.getAttribute("align"); }
|
||
// analyse les paires nom-valeur de l'élément param de l'objet HTML
|
||
var par = {};
|
||
var p = obj.getElementsByTagName("param");
|
||
var pl = p.length;
|
||
for (var j = 0; j < pl; j++) {
|
||
if (p[j].getAttribute("name").toLowerCase() != "movie") {
|
||
par[p[j].getAttribute("name")] = p[j].getAttribute("value");
|
||
}
|
||
}
|
||
showExpressInstall(att, par, id, cb);
|
||
}
|
||
else { // Les versions de Flash Player et de SWF ne correspondent pas ou un moteur Webkit ancien ignore les éléments param imbriqués de l'élément de l'objet HTML : afficher le contenu alternatif plutôt que le fichier SWF
|
||
displayAltContent(obj);
|
||
if (cb) { cb(cbObj); }
|
||
}
|
||
}
|
||
}
|
||
else { // si Flash Player n'est pas installé ou si la version fp ne peut pas être détectée, nous laissons l'élément de l'objet HTML faire son travail (afficher un fichier SWF ou un contenu alternatif)
|
||
setVisibility(id, true);
|
||
if (cb) {
|
||
var o = getObjectById(id); // vérifiez s'il existe ou non un élément d'objet HTML
|
||
if (o && typeof o.SetVariable != UNDEF) {
|
||
cbObj.success = true;
|
||
cbObj.ref = o;
|
||
}
|
||
cb(cbObj);
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
function getObjectById(objectIdStr) {
|
||
var r = null;
|
||
var o = getElementById(objectIdStr);
|
||
if (o && o.nodeName == "OBJECT") {
|
||
if (typeof o.SetVariable != UNDEF) {
|
||
r = o;
|
||
}
|
||
else {
|
||
var n = o.getElementsByTagName(OBJECT)[0];
|
||
if (n) {
|
||
r = n;
|
||
}
|
||
}
|
||
}
|
||
return r;
|
||
}
|
||
|
||
/* Configuration requise pour l'installation d'Adobe Express
|
||
- il n'est possible d'activer qu'une occurrence à la fois
|
||
- fp 6.0.65 ou version ultérieure
|
||
- SE Win/Mac uniquement
|
||
- aucun moteur Webkit d'une version antérieure à 312
|
||
*/
|
||
function canExpressInstall() {
|
||
return !isExpressInstallActive && hasPlayerVersion("6.0.65") && (ua.win || ua.mac) && !(ua.wk && ua.wk < 312);
|
||
}
|
||
|
||
/* Afficher la boîte de dialogue d'installation d'Adobe Express
|
||
- Référence : http://www.adobe.com/cfusion/knowledgebase/index.cfm?id=6a253b75
|
||
*/
|
||
function showExpressInstall(att, par, replaceElemIdStr, callbackFn) {
|
||
isExpressInstallActive = true;
|
||
storedCallbackFn = callbackFn || null;
|
||
storedCallbackObj = {success:false, id:replaceElemIdStr};
|
||
var obj = getElementById(replaceElemIdStr);
|
||
if (obj) {
|
||
if (obj.nodeName == "OBJECT") { // publication statique
|
||
storedAltContent = abstractAltContent(obj);
|
||
storedAltContentId = null;
|
||
}
|
||
else { // publication dynamique
|
||
storedAltContent = obj;
|
||
storedAltContentId = replaceElemIdStr;
|
||
}
|
||
att.id = EXPRESS_INSTALL_ID;
|
||
if (typeof att.width == UNDEF || (!/%$/.test(att.width) && parseInt(att.width, 10) < 310)) { att.width = "310"; }
|
||
if (typeof att.height == UNDEF || (!/%$/.test(att.height) && parseInt(att.height, 10) < 137)) { att.height = "137"; }
|
||
doc.title = doc.title.slice(0, 47) + " - Flash Player Installation";
|
||
var pt = ua.ie && ua.win ? "ActiveX" : "PlugIn",
|
||
fv = "MMredirectURL=" + win.location.toString().replace(/&/g,"%26") + "&MMplayerType=" + pt + "&MMdoctitle=" + doc.title;
|
||
if (typeof par.flashvars != UNDEF) {
|
||
par.flashvars += "&" + fv;
|
||
}
|
||
else {
|
||
par.flashvars = fv;
|
||
}
|
||
// IE uniquement : lorsqu'un fichier SWF est en cours de chargement (ET : non disponible en cache), attendez que le readyState de l'élément de l'objet devienne 4 avant de le supprimer,
|
||
// car vous ne pouvez pas annuler correctement un fichier SWF en cours de chargement sans rompre les références de chargement du navigateur et car obj.onreadystatechange ne fonctionne pas
|
||
if (ua.ie && ua.win && obj.readyState != 4) {
|
||
var newObj = createElement("div");
|
||
replaceElemIdStr += "SWFObjectNew";
|
||
newObj.setAttribute("id", replaceElemIdStr);
|
||
obj.parentNode.insertBefore(newObj, obj); // insérez l'espace réservé div qui sera remplacé par l'élément d'objet qui charge expressinstall.swf
|
||
obj.style.display = "none";
|
||
(function(){
|
||
if (obj.readyState == 4) {
|
||
obj.parentNode.removeChild(obj);
|
||
}
|
||
else {
|
||
setTimeout(arguments.callee, 10);
|
||
}
|
||
})();
|
||
}
|
||
createSWF(att, par, replaceElemIdStr);
|
||
}
|
||
}
|
||
|
||
/* Fonctions pour extraire et afficher le contenu alternatif
|
||
*/
|
||
function displayAltContent(obj) {
|
||
if (ua.ie && ua.win && obj.readyState != 4) {
|
||
// IE uniquement : lorsqu'un fichier SWF est en cours de chargement (ET : non disponible en cache), attendez que le readyState de l'élément de l'objet devienne 4 avant de le supprimer,
|
||
// car vous ne pouvez pas annuler correctement un fichier SWF en cours de chargement sans rompre les références de chargement du navigateur et car obj.onreadystatechange ne fonctionne pas
|
||
var el = createElement("div");
|
||
obj.parentNode.insertBefore(el, obj); // insérez l'espace réservé div qui sera remplacé par le contenu alternatif
|
||
el.parentNode.replaceChild(abstractAltContent(obj), el);
|
||
obj.style.display = "none";
|
||
(function(){
|
||
if (obj.readyState == 4) {
|
||
obj.parentNode.removeChild(obj);
|
||
}
|
||
else {
|
||
setTimeout(arguments.callee, 10);
|
||
}
|
||
})();
|
||
}
|
||
else {
|
||
obj.parentNode.replaceChild(abstractAltContent(obj), obj);
|
||
}
|
||
}
|
||
|
||
function abstractAltContent(obj) {
|
||
var ac = createElement("div");
|
||
if (ua.win && ua.ie) {
|
||
ac.innerHTML = obj.innerHTML;
|
||
}
|
||
else {
|
||
var nestedObj = obj.getElementsByTagName(OBJECT)[0];
|
||
if (nestedObj) {
|
||
var c = nestedObj.childNodes;
|
||
if (c) {
|
||
var cl = c.length;
|
||
for (var i = 0; i < cl; i++) {
|
||
if (!(c[i].nodeType == 1 && c[i].nodeName == "PARAM") && !(c[i].nodeType == 8)) {
|
||
ac.appendChild(c[i].cloneNode(true));
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
return ac;
|
||
}
|
||
|
||
/* Création d'un fichier SWF dynamique inter-navigateur
|
||
*/
|
||
function createSWF(attObj, parObj, id) {
|
||
var r, el = getElementById(id);
|
||
if (ua.wk && ua.wk < 312) { return r; }
|
||
if (el) {
|
||
if (typeof attObj.id == UNDEF) { // si aucun 'id' n'est défini pour l'élément d'objet, il héritera de l''id' du contenu alternatif
|
||
attObj.id = id;
|
||
}
|
||
if (ua.ie && ua.win) { // Internet Explorer + l’élément de l’objet HTML + les méthodes DOM W3C ne se combinent pas : retour à outerHTML
|
||
var att = "";
|
||
for (var i in attObj) {
|
||
if (attObj[i] != Object.prototype[i]) { // filtrez les ajouts de prototypes d'autres bibliothèques potentielles
|
||
if (i.toLowerCase() == "data") {
|
||
parObj.movie = attObj[i];
|
||
}
|
||
else if (i.toLowerCase() == "styleclass") { // 'class' est un mot-clé réservé ECMA4
|
||
att += ' class="' + attObj[i] + '"';
|
||
}
|
||
else if (i.toLowerCase() != "classid") {
|
||
att += ' ' + i + '="' + attObj[i] + '"';
|
||
}
|
||
}
|
||
}
|
||
var par = "";
|
||
for (var j in parObj) {
|
||
if (parObj[j] != Object.prototype[j]) { // filtrez les ajouts de prototypes d'autres bibliothèques potentielles
|
||
par += '<param name="' + j + '" value="' + parObj[j] + '" />';
|
||
}
|
||
}
|
||
el.outerHTML = '<object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000"' + att + '>' + par + '</object>';
|
||
objIdArr[objIdArr.length] = attObj.id; // enregistré pour réparer les 'fuites' d'objets lors de la purge (publication dynamique uniquement)
|
||
r = getElementById(attObj.id);
|
||
}
|
||
else { // navigateurs qui se comportent correctement
|
||
var o = createElement(OBJECT);
|
||
o.setAttribute("type", FLASH_MIME_TYPE);
|
||
for (var m in attObj) {
|
||
if (attObj[m] != Object.prototype[m]) { // filtrez les ajouts de prototypes d'autres bibliothèques potentielles
|
||
if (m.toLowerCase() == "styleclass") { // 'class' est un mot-clé réservé ECMA4
|
||
o.setAttribute("class", attObj[m]);
|
||
}
|
||
else if (m.toLowerCase() != "classid") { // filtrez l'attribut spécifique d'IE
|
||
o.setAttribute(m, attObj[m]);
|
||
}
|
||
}
|
||
}
|
||
for (var n in parObj) {
|
||
if (parObj[n] != Object.prototype[n] && n.toLowerCase() != "movie") { // filtrez les ajouts de prototypes d'autres bibliothèques potentielles et l'élément param propre à IE
|
||
createObjParam(o, n, parObj[n]);
|
||
}
|
||
}
|
||
el.parentNode.replaceChild(o, el);
|
||
r = o;
|
||
}
|
||
}
|
||
return r;
|
||
}
|
||
|
||
function createObjParam(el, pName, pValue) {
|
||
var p = createElement("param");
|
||
p.setAttribute("name", pName);
|
||
p.setAttribute("value", pValue);
|
||
el.appendChild(p);
|
||
}
|
||
|
||
/* Suppression d'un fichier SWF inter-navigateur
|
||
- Particulièrement nécessaire pour supprimer complètement et en toute sécurité un fichier SWF dans Internet Explorer
|
||
*/
|
||
function removeSWF(id) {
|
||
var obj = getElementById(id);
|
||
if (obj && obj.nodeName == "OBJECT") {
|
||
if (ua.ie && ua.win) {
|
||
obj.style.display = "none";
|
||
(function(){
|
||
if (obj.readyState == 4) {
|
||
removeObjectInIE(id);
|
||
}
|
||
else {
|
||
setTimeout(arguments.callee, 10);
|
||
}
|
||
})();
|
||
}
|
||
else {
|
||
obj.parentNode.removeChild(obj);
|
||
}
|
||
}
|
||
}
|
||
|
||
function removeObjectInIE(id) {
|
||
var obj = getElementById(id);
|
||
if (obj) {
|
||
for (var i in obj) {
|
||
if (typeof obj[i] == "function") {
|
||
obj[i] = null;
|
||
}
|
||
}
|
||
obj.parentNode.removeChild(obj);
|
||
}
|
||
}
|
||
|
||
/* Fonctions pour optimiser la compression JavaScript
|
||
*/
|
||
function getElementById(id) {
|
||
var el = null;
|
||
try {
|
||
el = doc.getElementById(id);
|
||
}
|
||
catch (e) {}
|
||
return el;
|
||
}
|
||
|
||
function createElement(el) {
|
||
return doc.createElement(el);
|
||
}
|
||
|
||
/* Fonction attachEvent mise à jour pour Internet Explorer
|
||
- Enregistre les informations de la fonction attachEvent dans un tableau afin que les fonctions detachEvent puissent être appelées lors de la purge en vue d'éviter des fuites de mémoire
|
||
*/
|
||
function addListener(target, eventType, fn) {
|
||
target.attachEvent(eventType, fn);
|
||
listenersArr[listenersArr.length] = [target, eventType, fn];
|
||
}
|
||
|
||
/* Correspondance de version entre Flash Player et le contenu SWF
|
||
*/
|
||
function hasPlayerVersion(rv) {
|
||
var pv = ua.pv, v = rv.split(".");
|
||
v[0] = parseInt(v[0], 10);
|
||
v[1] = parseInt(v[1], 10) || 0; // prend en charge la notation abrégée, par exemple "9" au lieu de "9.0.0"
|
||
v[2] = parseInt(v[2], 10) || 0;
|
||
return (pv[0] > v[0] || (pv[0] == v[0] && pv[1] > v[1]) || (pv[0] == v[0] && pv[1] == v[1] && pv[2] >= v[2])) ? true : false;
|
||
}
|
||
|
||
/* Création de feuilles de style de texte dynamique inter-navigateur
|
||
- Selon la solution proposée par Bobby van der Sluis : http://www.bobbyvandersluis.com/articles/dynamicCSS.php
|
||
*/
|
||
function createCSS(sel, decl, media, newStyle) {
|
||
if (ua.ie && ua.mac) { return; }
|
||
var h = doc.getElementsByTagName("head")[0];
|
||
if (!h) { return; } // pour également prendre en charge les pages HTML incorrectement programmées ne disposant pas d'élément d'en-tête
|
||
var m = (media && typeof media == "string") ? media : "screen";
|
||
if (newStyle) {
|
||
dynamicStylesheet = null;
|
||
dynamicStylesheetMedia = null;
|
||
}
|
||
if (!dynamicStylesheet || dynamicStylesheetMedia != m) {
|
||
// créez un feuille de style dynamique + obtenez une référence globale à cette feuille
|
||
var s = createElement("style");
|
||
s.setAttribute("type", "text/css");
|
||
s.setAttribute("media", m);
|
||
dynamicStylesheet = h.appendChild(s);
|
||
if (ua.ie && ua.win && typeof doc.styleSheets != UNDEF && doc.styleSheets.length > 0) {
|
||
dynamicStylesheet = doc.styleSheets[doc.styleSheets.length - 1];
|
||
}
|
||
dynamicStylesheetMedia = m;
|
||
}
|
||
// ajoutez une règle de style
|
||
if (ua.ie && ua.win) {
|
||
if (dynamicStylesheet && typeof dynamicStylesheet.addRule == OBJECT) {
|
||
dynamicStylesheet.addRule(sel, decl);
|
||
}
|
||
}
|
||
else {
|
||
if (dynamicStylesheet && typeof doc.createTextNode != UNDEF) {
|
||
dynamicStylesheet.appendChild(doc.createTextNode(sel + " {" + decl + "}"));
|
||
}
|
||
}
|
||
}
|
||
|
||
function setVisibility(id, isVisible) {
|
||
if (!autoHideShow) { return; }
|
||
var v = isVisible ? "visible" : "hidden";
|
||
if (isDomLoaded && getElementById(id)) {
|
||
getElementById(id).style.visibility = v;
|
||
}
|
||
else {
|
||
createCSS("#" + id, "visibility:" + v);
|
||
}
|
||
}
|
||
|
||
/* Filtrez pour éviter les attaques XSS
|
||
*/
|
||
function urlEncodeIfNecessary(s) {
|
||
var regex = /[\\\"<>\.;]/;
|
||
var hasBadChars = regex.exec(s) != null;
|
||
return hasBadChars && typeof encodeURIComponent != UNDEF ? encodeURIComponent(s) : s;
|
||
}
|
||
|
||
/* Libérez de la mémoire pour éviter les fuites de mémoire provoquées par les fermetures, réparez les fils audio/vidéo bloqués et forcez la déconnexion des sockets ouverts/NetConnections (Internet Explorer uniquement)
|
||
*/
|
||
var cleanup = function() {
|
||
if (ua.ie && ua.win) {
|
||
window.attachEvent("onunload", function() {
|
||
// supprimez les écouteurs pour éviter les fuites de mémoire
|
||
var ll = listenersArr.length;
|
||
for (var i = 0; i < ll; i++) {
|
||
listenersArr[i][0].detachEvent(listenersArr[i][1], listenersArr[i][2]);
|
||
}
|
||
// nettoyez dynamiquement les objets incorporés pour réparer les fils audio/vidéo, et forcez la déconnexion des sockets ouverts et des NetConnections
|
||
var il = objIdArr.length;
|
||
for (var j = 0; j < il; j++) {
|
||
removeSWF(objIdArr[j]);
|
||
}
|
||
// nettoyez les fermetures de la bibliothèque principale pour éviter les fuites de mémoire
|
||
for (var k in ua) {
|
||
ua[k] = null;
|
||
}
|
||
ua = null;
|
||
for (var l in swfobject) {
|
||
swfobject[l] = null;
|
||
}
|
||
swfobject = null;
|
||
});
|
||
}
|
||
}();
|
||
|
||
return {
|
||
/* API publique
|
||
- Référence : http://code.google.com/p/swfobject/wiki/documentation
|
||
*/
|
||
registerObject: function(objectIdStr, swfVersionStr, xiSwfUrlStr, callbackFn) {
|
||
if (ua.w3 && objectIdStr && swfVersionStr) {
|
||
var regObj = {};
|
||
regObj.id = objectIdStr;
|
||
regObj.swfVersion = swfVersionStr;
|
||
regObj.expressInstall = xiSwfUrlStr;
|
||
regObj.callbackFn = callbackFn;
|
||
regObjArr[regObjArr.length] = regObj;
|
||
setVisibility(objectIdStr, false);
|
||
}
|
||
else if (callbackFn) {
|
||
callbackFn({success:false, id:objectIdStr});
|
||
}
|
||
},
|
||
|
||
getObjectById: function(objectIdStr) {
|
||
if (ua.w3) {
|
||
return getObjectById(objectIdStr);
|
||
}
|
||
},
|
||
|
||
embedSWF: function(swfUrlStr, replaceElemIdStr, widthStr, heightStr, swfVersionStr, xiSwfUrlStr, flashvarsObj, parObj, attObj, callbackFn) {
|
||
var callbackObj = {success:false, id:replaceElemIdStr};
|
||
if (ua.w3 && !(ua.wk && ua.wk < 312) && swfUrlStr && replaceElemIdStr && widthStr && heightStr && swfVersionStr) {
|
||
setVisibility(replaceElemIdStr, false);
|
||
addDomLoadEvent(function() {
|
||
widthStr += ""; // conversion automatique en chaîne
|
||
heightStr += "";
|
||
var att = {};
|
||
if (attObj && typeof attObj === OBJECT) {
|
||
for (var i in attObj) { // copiez l'objet pour éviter l'utilisation de références, car les programmateurs Web réutilisent souvent attObj pour plusieurs fichiers SWF
|
||
att[i] = attObj[i];
|
||
}
|
||
}
|
||
att.data = swfUrlStr;
|
||
att.width = widthStr;
|
||
att.height = heightStr;
|
||
var par = {};
|
||
if (parObj && typeof parObj === OBJECT) {
|
||
for (var j in parObj) { // copiez l'objet pour éviter l'utilisation de références, car les programmateurs Web réutilisent souvent parObj pour plusieurs fichiers SWF
|
||
par[j] = parObj[j];
|
||
}
|
||
}
|
||
if (flashvarsObj && typeof flashvarsObj === OBJECT) {
|
||
for (var k in flashvarsObj) { // copiez l'objet pour éviter l'utilisation de références, car les programmateurs Web réutilisent souvent flashvarsObj pour plusieurs fichiers SWF
|
||
if (typeof par.flashvars != UNDEF) {
|
||
par.flashvars += "&" + k + "=" + flashvarsObj[k];
|
||
}
|
||
else {
|
||
par.flashvars = k + "=" + flashvarsObj[k];
|
||
}
|
||
}
|
||
}
|
||
if (hasPlayerVersion(swfVersionStr)) { // créez un fichier SWF
|
||
var obj = createSWF(att, par, replaceElemIdStr);
|
||
if (att.id == replaceElemIdStr) {
|
||
setVisibility(replaceElemIdStr, true);
|
||
}
|
||
callbackObj.success = true;
|
||
callbackObj.ref = obj;
|
||
}
|
||
else if (xiSwfUrlStr && canExpressInstall()) { // affichez la fenêtre d'installation d'Adobe Express
|
||
att.data = xiSwfUrlStr;
|
||
showExpressInstall(att, par, replaceElemIdStr, callbackFn);
|
||
return;
|
||
}
|
||
else { // affichez le contenu alternatif
|
||
setVisibility(replaceElemIdStr, true);
|
||
}
|
||
if (callbackFn) { callbackFn(callbackObj); }
|
||
});
|
||
}
|
||
else if (callbackFn) { callbackFn(callbackObj); }
|
||
},
|
||
|
||
switchOffAutoHideShow: function() {
|
||
autoHideShow = false;
|
||
},
|
||
|
||
ua: ua,
|
||
|
||
getFlashPlayerVersion: function() {
|
||
return { major:ua.pv[0], minor:ua.pv[1], release:ua.pv[2] };
|
||
},
|
||
|
||
hasFlashPlayerVersion: hasPlayerVersion,
|
||
|
||
createSWF: function(attObj, parObj, replaceElemIdStr) {
|
||
if (ua.w3) {
|
||
return createSWF(attObj, parObj, replaceElemIdStr);
|
||
}
|
||
else {
|
||
return undefined;
|
||
}
|
||
},
|
||
|
||
showExpressInstall: function(att, par, replaceElemIdStr, callbackFn) {
|
||
if (ua.w3 && canExpressInstall()) {
|
||
showExpressInstall(att, par, replaceElemIdStr, callbackFn);
|
||
}
|
||
},
|
||
|
||
removeSWF: function(objElemIdStr) {
|
||
if (ua.w3) {
|
||
removeSWF(objElemIdStr);
|
||
}
|
||
},
|
||
|
||
createCSS: function(selStr, declStr, mediaStr, newStyleBoolean) {
|
||
if (ua.w3) {
|
||
createCSS(selStr, declStr, mediaStr, newStyleBoolean);
|
||
}
|
||
},
|
||
|
||
addDomLoadEvent: addDomLoadEvent,
|
||
|
||
addLoadEvent: addLoadEvent,
|
||
|
||
getQueryParamValue: function(param) {
|
||
var q = doc.location.search || doc.location.hash;
|
||
if (q) {
|
||
if (/\?/.test(q)) { q = q.split("?")[1]; } // supprimez le point d'interrogation
|
||
if (param == null) {
|
||
return urlEncodeIfNecessary(q);
|
||
}
|
||
var pairs = q.split("&");
|
||
for (var i = 0; i < pairs.length; i++) {
|
||
if (pairs[i].substring(0, pairs[i].indexOf("=")) == param) {
|
||
return urlEncodeIfNecessary(pairs[i].substring((pairs[i].indexOf("=") + 1)));
|
||
}
|
||
}
|
||
}
|
||
return "";
|
||
},
|
||
|
||
// Pour usage interne uniquement
|
||
expressInstallCallback: function() {
|
||
if (isExpressInstallActive) {
|
||
var obj = getElementById(EXPRESS_INSTALL_ID);
|
||
if (obj && storedAltContent) {
|
||
obj.parentNode.replaceChild(storedAltContent, obj);
|
||
if (storedAltContentId) {
|
||
setVisibility(storedAltContentId, true);
|
||
if (ua.ie && ua.win) { storedAltContent.style.display = "block"; }
|
||
}
|
||
if (storedCallbackFn) { storedCallbackFn(storedCallbackObj); }
|
||
}
|
||
isExpressInstallActive = false;
|
||
}
|
||
}
|
||
};
|
||
}();
|