CSS : un style assez joli pour un formulaire


12 août 2011

Voici une classe CSS (cross-platform) que je trouve agréable et qui sied plutôt bien à l'hébergement de formulaires courts :

Champ 1 :
Champ 1 :

C'est mignon d'avoir pensé à une ombre, à des coins arrondis et à un gradient interne. C'est anglais en plus.

Evaluation et calcul d'expression


1 août 2011

Il m'est arrivé d'avoir besoin d'évaluer des expressions arithmétiques dans du code Javascript, aussi bien pour une calculatrice toute simple que pour un tableur spécifique pour un client ou encore un moteur de génération de L-Systems paramétriques. J'ai donc décidé d'isoler ce code assez simple et de l'isoler dans un module réutilisable. Pour tester cette fonctionnalité, amusez-vous avec la zone de saisie ci-dessous :

Ce module gère bien sûr les 4 opérations de base, l'opérateur module (%), l'élévation à la puissance (grâce à **) et les parenthèses. De plus, il permet au développeur de se brancher sur l'objet d'évaluation pour être notifié en cas d'utilisation de symboles dans l'expression. Ces symboles peuvent être des variables ou des fonctions avec leurs arguments. Voici un exemple d'utilisation illustrant toutes les fonctionnalités :

var Calculator = new Evaluator({
        variable:function(varName)      {
            return ...;     //Renvoie la valeur de la variable *varName* que le programme gère.
        },
        callback:function(funcName, args)       {
            //Exemples d'utilisation
            if (funcName == "sqrt")     return Math.sqrt(args);
            if (funcName == "sin")      return Math.sin(args);
            if (funcName == "cos")      return Math.cos(args);
        }
    });
    //
    var Result = Calculator.eval("34-75*3+(4*8*2-4+6%5*2)-12*(15%7-3*2)+7").result;

Et oui, c'est rapide et simple à utiliser !

Pour info, le parsing / analyse de l'expression se fait de gauche à droite avec une machine à état, c'est plutôt rapide, mais je ne stocke aucun arbre me permettant d'optimiser les évaluation multiples d'une même expression dont les paramètres changeraient. Le code n'est vraiment pas difficile à modifier pour ajouter cette fonctionnalité.

Pour intégrer ce module dans votre code, il suffit simplement d'inclure le script directement dans votre page, qui pèse 1639 octets avant compression et 864 octets en zippé. �a ne devrait pas alourdir vos pages :)

JS : fonctions et propriétés globales


15 juillet 2011

Il y a parfois besoin d'accéder à des propriétés (variables/fonctions) globales d'un objet. On peut arguer que dans ce cas-là une simple variable/fonction définie dans le namespace global suffirait (et on n'aurait pas tort) mais si l'utilisation d'un singleton peut paraître plus séduisant, car on minimise les collisions de nom dans ce même espace global, on est confronté à l'absurdité d'appeler une méthode de cet objet alors que cette fonction n'utilise rien de ce même objet. L'appel à une fonction/variables globale dans ce cadre prend simplement la forme suivante :

MonObjet.prototype.MaFonctionGlobale(les paramètres)

Il faut donc juste utiliser le constructeur et son prototype pour adresser la fonction ou la variable. C'est plus long ? Oui, mais parfois il faut indiquer que cette méthode est globale et c'est une très bonne façon de faire.

JS : décomposition d'un new


11 juillet 2011

Voici ma version d'un new en JS :

operator    new(Constructor)        {
    var Instance = {}
    Instance.constructor = Constructor
    Instance.prototype = Constructor.prototype
    var RetVal = Constructor.apply(Instance)
    return typeof RetVal == "undefined" ? Instance : RetVal
}

�a permet de comprendre facilement le langage et sa manière d'opérer.

Web : première extension Chrome


30 mai 2011

J'avais besoin de pouvoir stocker toutes les pages ouvertes au sein de toutes les instances de Chrome ouvertes et j'ai donc pour cela réalisé ma première extension. Il faut savoir que je n'ai eu besoin que d'un fichier manifest.json décrivant l'extension et d'un fichier HTML classique avec le code Javascript qui va bien. Les deux fichiers sont à stocker dans un dossier à charger depuis la page chrome://extensions/.

<!DOCTYPE html>
<html>
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
    <script>
        var Output = "";    var LinkId = 0;
        var AllWindows = chrome.windows.getAll({populate:true}, function(wnds)  {
            for (var WIdx in wnds)      {
                var WndDiv = document.createElement("div");
                WndDiv.id = "wnd-"+wnds[WIdx].id;
                document.getElementById("content").appendChild(WndDiv);
                WndDiv["innerHTML"] += "<div>Fenêtre d'Id "+wnds[WIdx].id+</div>\n";
                (function(wid)      {
                    chrome.tabs.getAllInWindow(wid, function(tabs)      {
                        for(var TIdx in tabs)       {
                            document.getElementById("wnd-"+wid).innerHTML += 
                                (LinkId++)+" :<a href='"+tabs[TIdx].url+"'>"+
                                    tabs[TIdx].title+</a><br/>\n";
                        }
                    })
                })(wnds[WIdx].id);
            }
        })
    </script>
    <style>
        body    {   width:800px;    height:400px;   }
        #title  {   text-align:center;  font-weight:bold;   background-color:#CCC;      }
        #content > div > div    {   color:#FF8888;  font-weight:bold;   font-size:100%; }
        #content > div          {   color:black;    font-size:80%;  }
        #content > div > a      {   color:blue; }
    </style>
</head>
<body>
    <div id='title'>Fenêtres overtes</div>
    <div id='content'></div>
</body>
</html>

{ 
    "format_version": 1, 
    "id": "a16656a039d8b23731b3e933914f8bd7",
    "version": "1.0", 
    "name": "Opened URLs exporter", 
    "description": "Extraction des URLs de tous les tabs de toutes les fenêtres Chrome en cours d'exécution",
    "permissions": ["tabs"],
    "browser_action": {
        "default_icon": "icon.png",
        "popup":"tool.html"
    }
} 

Et quand je clique dans l'icône de l'extension de la barre d'outil j'avais mes 75 URLs qui étaient affichées (presque) joliment.

Accueil1 2 3 4 5 6 7