CSS3 PIE pour créer un border-radius sur IE [webdesign]

Si vous cherchez à faire un border-radius sur un vieux IE vous avez dû vous rendre compte que cela ne fonctionne pas… mais heureusement il existe CSS3 PIE qui est un « petit » fichier qui va permettre de créer l’effet désiré !

A noter cependant que je rencontre un problème : lorsque j’applique le fichier htc avec behavior alors j’ai ma couleur de fond (background-color) qui devient invisible / disparait. Ce problème peut-être résolu en appliquant la règle CSS suivante (solution trouvée sur leur forum):

* { position:relative }

Grâce à ça tout fonctionne sous IE 🙂

Transformer/convertir une vidéo vers le format mp4 et ogg (ogv) gratuitement [vidéo]

Il existe une extension pour Firefox qui permet de convertir tout type de vidéo (avi, wmv, mp4, etc) dans le format HTML5 Ogg ou WebM. Il s’agit de http://firefogg.org/.
Vous aurez besoin de Firefox 4 au moins. Cliquez sur le bouton rouge « Install Firefogg ». Vous devrez redémarrer votre Firefox, puis retournez sur http://firefogg.org/. Cette fois cliquez sur « Make web video » et suivez les instructions !

Trouver les paramètres dans une url en javascript [programmation]

[niveau débutant]

Voici une fonction courte pour récupérer l’ensemble des paramètres passés dans l’URL :

function getUrlVars(a,b,c,d){b=[];if(a=location.search.split('#')[0].match(/\?(.*)(#.*)?/)){d=a[1].split('&');for(i=d.length;i--;){c=d[i].split('=');b[i]=c[0];b[c[0]]=decodeURIComponent(c[1]).replace(/\+/g," ")}}return b}

var params=getUrlVars();
// si on a http://blog.kodono.info/?foo=bar&gniii=ok#something alors :
params[0]; // -> 'foo'
params[1]; // -> 'gniii'
params["foo"]; // -> 'bar'
params["gniii"]; // -> 'ok'

Comment cropper / rogner / recadrer un film [Vidéo]

[niveau débutant]

J’ai découvert qu’il était très simple d’enlever des bouts du cadrage d’un film grâce à AviDemux !

Il vous suffit d’ouvrir votre film avec AviDemux puis dans la colonne de gauche choisissez un format vidéo de sortie. On prendra par exemple xvid et ensuite cliquez sur « Filtres » :
Copie d'écran des boutons

Parmi les filtres disponibles double cliquez sur « Crop ». A partir de là vous pouvez définir la marge gauche, droite, haute et basse que vous voulez rogner :
Fenêtre de crop

Une fois terminé, cliquez sur « Fermer », puis dans la fenêtre principale du logiciel, dans la colonne de gauche, sélectionner le format audio voulu (par exemple mp3), et ainsi que le format de sortie (avi).
Si jamais, au moment où vous cliquez sur « Fermer » vous obtenez le message « Width is not a multiple of 8 » :
Message d'erreur
Pour régler ce problème il faut revenir à votre filtre « Crop ». Vous devez regarder la largeur de la vidéo que vous allez produire :
Exemple de largeur de vidéo
Dans cet exemple on a 478, or ce n’est pas un multiple de 8 (car 478/8=59.75). Il suffit donc de modifier légèrement la bordure droite ou gauche afin d’obtenir une taille multiple de huit. Si j’ai 480 alors ça sera bon (480/8=60).

Il ne vous reste plus qu’à enregistrer votre film et le tour est joué.

Un algorithme court et rapide pour Array.unique() [Javascript]

Voici un simple algorithme, et apparemment rapide, trouvé sur http://www.shamasis.net/2009/09/fast-algorithm-to-find-unique-items-in-javascript-array/ et que j’ai raccourci légèrement :

Array.prototype.unique=[].unique||function(){var o={},i,l=this.length,r=[];for(i=0;i<l;i++)o[this[i]]=this[i];for(i in o)r.push(o[i]);return r}

// or, if you don't want to override the Array prototype:
var ArrayUnique = function(arr){var o={},i,l=arr.length,r=[];for(i=0;i<l;i++)o[arr[i]]=arr[i];for(i in o)r.push(o[i]);return r}

// exemple
var tab=[1, 5, 2, 4, 1, 5, 4, 1, 5, 6, 8 ];
var tabUniq=tab.unique(); // [1, 5, 2, 4, 6, 8]

Alternatives à IMNRC() et ProcessImn() pour déterminer la présence d’une personne [Sharepoint]

Avec Sharepoint (2003 & 2007) on peut voir la présence (sur IM/MSN/Microsoft Messenger/Office Messenger/Microsoft Lynk) des utilisateurs directement dans une page Web grâce à des petites bulles de couleur. Quand on place le curseur au-dessus on aperçoit un popup avec diverses informations et possibilités. Cela n’est disponible que pour Internet Explorer puisqu’on utilise ici de l’ActiveX (et en particulier NameCtrl).

Je force le mode standard d’IE dans mon Sharepoint, et j’ai remarqué que les fonctions ProcessImn() et IMNRC() (l’une appelant l’autre) causaient un plantage d’IE avec un CPU qui montait en charge, et cela pour les pages qui contiennent un grand nombre de personnes et donc de bulles de présence (typiquement une liste AllItems avec des colonnes qui montrent cette information).
J’ai donc décidé de créer une alternative à l’affichage de la présence dans Sharepoint en utilisant mes propres fonctions.

Le résultat est le suivant :

/* on commence par supprimer les deux fonctions qui posent problèmes */
function IMNRC() {}
function ProcessImn() {}
var nameCtrl; // on s'assure de définir nameCtrl
var presence={}; // on crée un objet presence qui va nous servir à mettre en cache l'état de chaque individu
// Cette fonction fait apparaitre un menu/popup avec les informations de présence de l'utilisateur
function showIMMenu() {
  var el=window.event.srcElement;
  var pos=el.getBoundingClientRect();
  // on place le menu en question à la position pos.left et pos.top
  nameCtrl.ShowOOUI(el.getAttribute("sip"), 0, pos.left, pos.top);
}

// Cette fonction va cacher le menu
function hideIMMenu() { nameCtrl.HideOOUI() }

// Cette fonction va permettre de modifier la bulle avec celle qui correspond à l'état de présence de l'utilisateur
function ChangeIMPresence(sip, state, imgID) {
  if (presence[imgID] == state) return;
  presence[imgID]=state;
  var imgIM=document.getElementsByName(imgID);
  for (var i=0; i<imgIM.length; i++) {
    var alt="",src="imnhdr.gif"; // default image (grey)
    switch(state) {
      case 0: alt="Online"; src="imnon.png"; break;
      case 1: alt="Offline"; src="imnoff.png"; break;
      case 2: alt="Away"; src="imnaway.png"; break;
      case 4: alt="Be Right Back"; src="imnaway.png"; break;
      case 3: alt="Busy"; src="imnbusy.png"; break;
      case 5: alt="On the Phone"; src="imnbusy.png"; break;
      case 6: alt="Out to Lunch"; src="imnaway.png"; break;
      default: alt="Unknown"; src="imnhdr.gif";
    }
    imgIM[i].src="http://your_sharepoint/_layouts/images/"+src;
    imgIM[i].alt=alt;
  }
}

// Maintenant on initialise l'objet ActiveX
function initIMPresence() {
  if (typeof ActiveXObject == "function") { // seulement pour IE
    if (typeof nameCtrl=="undefined") nameCtrl=new ActiveXObject('Name.NameCtrl.1');
    var imgIM=document.getElementsByName("imnmark"); // toutes les bulles de présence ont le nom "imnmark"
    for (var i=0; i<imgIM.length; i++) {
      var sip=imgIM[i].getAttribute("sip"); // l'attribut "sip" retourne l'information que l'on souhaite
      if (sip!=null) {
        sip=sip.slice(4);
        var state=nameCtrl.GetStatus(sip, "imnmark_"+sip); // retourne la présence basée sur le SIP (adresse email)
        nameCtrl.OnStatusChange=ChangeIMPresence;
        imgIM[i].src="http://your_sharepoint/_layouts/images/imnhdr.gif";
        imgIM[i].alt="Unknown";
        imgIM[i].name+="_"+sip;
        imgIM[i].onclick=showIMMenu;
        imgIM[i].onmouseover=showIMMenu; // quand on passe la souris au-dessus d'une bulle on verra le menu
        imgIM[i].onmouseout=hideIMMenu;
      }
    }
  }
}

// et on lance tout ça !
initIMPresence();

En ajoutant ce bout de code à ma masterpage j’ai pu conserver les bulles de présence tout en évitant un plantage d’IE 🙂

DOMContentLoaded pour cross browser (multi-navigateurs) [Javascript]

Après avoir parcouru le Net pour un évènement DOMContentLoaded (qui s’enclenche avant window.onload) qui puisse fonctionner sur tous les navigateurs (et en particulier IE7), j’ai pu trouver un article qui explique bien les différentes étapes et la solution adaptée : http://javascript.info/tutorial/onload-ondomcontentloaded

Pour résumer la fonction à utiliser est :

function bindReady(handler){
  var called = false
  function ready() { 
    if (called) return
    called = true
    handler()
  }
  if ( document.addEventListener ) { // native event
    document.addEventListener( "DOMContentLoaded", ready, false )
  } else if ( document.attachEvent ) {  // IE
    try { var isFrame = window.frameElement != null } catch(e) {}

    // IE, the document is not inside a frame
    if ( document.documentElement.doScroll && !isFrame ) {
      function tryScroll(){
        if (called) return
        try {
          document.documentElement.doScroll("left")
          ready()
        } catch(e) {
          setTimeout(tryScroll, 10)
        }
      }
      tryScroll()
    }

    // IE, the document is inside a frame
    document.attachEvent("onreadystatechange", function(){
      if ( document.readyState === "complete" ) {
        ready()
      }
    })
  }

  // Old browsers
  if (window.addEventListener)
    window.addEventListener('load', ready, false)
  else if (window.attachEvent)
    window.attachEvent('onload', ready)
  else {
    var fn = window.onload // very old browser, copy old onload
    window.onload = function() { // replace by new onload and call the old one
      fn && fn()
      ready()
    }
  }
}

A partir de là vous pouvez appeler votre fonction avec :

bindReady(function() {
  /* quelque chose qui doit se lancer après le chargement du DOM */
});

Dans le cas où vous voudriez appeler plusieurs fonctions, alors vous pouvez simplement faire quelque chose comme :

var fonctionsACharger=[];
bindReady(function() {
  for (var i=0; i<functionsACharger.length;i++) functionsACharger[i]();
});

/* on ajoute les fonctions à charger dans notre tableau */
fonctionsACharger.push(function() {
  /* première chose à faire */
});
fonctionsACharger.push(function() {
  alert("Toutes les fonctions sont maintenant chargées !");
});

IE9 en mode standard et Sharepoint… bug du bouton OK [Sharepoint]

[niveau expert]

Si vous passez IE9 en mode standard avec Sharepoint vous risquez d’avoir le bouton OK des formulaires qui ne fonctionne plus… Après avoir debuggué le bazar j’ai découvert qu’un des fichiers (« /_layouts/1033/form.js ») Javascript utilise document.frames() au lieu de document.frames[]. Si cela fonctionne sur les anciens navigateurs, ce n’est plus le cas pour IE9 en mode standard, du coup il retourne un « Function expected ».

Il y a deux fonctions incriminées RTE_GetEditorIFrame() et RTE_DD_GetMenuFrame(). Il suffit d’utiliser les commentaires conditionnels pour indiquer que lorsqu’on utilise IE9 alors on remplace ces deux fonctions par :

function RTE_GetEditorIFrame(strBaseElementID)
{
	var ifmEditor=null;
	var doc=document;
	if ((null !=doc.frames) && (doc.frames.length==0) && (doc.parentWindow.parent !=null))
	{
		doc=doc.parentWindow.parent.document;
	}
	if ((null !=doc.frames) && (doc.frames.length > 0))
	{
		var ifmContainer=doc.getElementById(RTE_GetEditorIFrameID(strBaseElementID));
		if (ifmContainer !=null)
		{
			ifmEditor=doc.frames[RTE_GetEditorIFrameID(strBaseElementID)];
		}
	}
	return ifmEditor;
}
function RTE_DD_GetMenuFrame()
{
	var ifmMenu=null;
	var elemMenu=RTE_DD_GetMenuElement();
	if (null !=elemMenu)
	{
		if (document.frames.length > 0)
		{
			ifmMenu=document.frames[g_strRTETextEditorPullDownMenuID];
		}
		else
		{
			if ((document.parentWindow !=null) && (document.parentWindow.frames !=null))
			{
				ifmMenu=document.parentWindow.parent.document.frames[g_strRTETextEditorPullDownMenuID];
			}
		}
	}
	if (null==ifmMenu)
	{
		if (g_fRTEFirstCallToGetMenu)
		{
			g_fRTEFirstCallToGetMenu=false;
			return null;
		}
	}
	return ifmMenu;
}

Ainsi document.frames est bien appelé comme un objet et non comme une fonction !

A noter cependant qu’il existe des tonnes de bugs avec IE9 et Sharepoint 2003/2007. Il est donc conseillé d’utiliser le mode de compatibilité en IE8 si vous ne voulez pas passer des heures à trouver l’origine des problèmes et à les corriger :

<meta http-equiv="X-UA-Compatible" content="IE=8"/>

Appeler un lien relatif dans une masterpage [Sharepoint]

J’ai eu le cas où j’avais besoin d’appeler un fichier Javascript à la racine de tous mes sites Sharepoint (et donc avec un lien relatif au site consulté). Pour cela j’ai modifié la masterpage en y ajoutant la ligne suivante :

<script type="text/javascript" src='<asp:Literal runat="server" Text="<% $SPUrl:~Site/customized.js %>"></asp:Literal>'>

C’est donc <asp:Literal runat="server" Text="<% $SPUrl:~Site/customized.js %>"></asp:Literal> qui fait tout le boulot. Et bien sûr vous pouvez utiliser asp:Literal pour d’autres appels de fichiers !

Define the preview image for your masterpage [Sharepoint]

You can easily define the preview image for your masterpage : just go to the Master Page Gallery (e.g. : http://your.server.com/your/root/dir/_catalogs/masterpage/) and find your masterpage in the collection. Then move your mouse hover to have the downward arrow that appears to open its context menu. Choose « Edit Properties », and you’ll see a Preview Image section 🙂

For your information, the image should 216px × 160px