Ce blog a déménagé et parle maintenant uniquement anglais.

This blog has moved and now only speaks English.


See you there!


le blog de florian cargoet : du linux, du web et du logiciel libre

Categorie: Webdev

A propos du web, de son contenu, de ses outils...

Sous-catégories disponibles :

[EN] Use PhantomJS to take screenshots of your webapp for you

6 January, 2012 (20:51) | Ext JS, Webdev | Florian Cargoet


You’ve built a web application and it’s time to write the user documentation. Your app is localized and you ship new features every three months.

In your documentation, you want screenshots of specific parts of your application: the login box, the collapsed Help panel, the main data grid…

You need to take screenshots in 4 languages.

Do you want to take them manually? You could probably define a bunch of rectangular zones and automate the process but the login box is bigger in French than in English since the text is longer. And in six months, you’ll ship a feature which will require a change in the global application layout.

Do you want to define your rectangular zones 4 times? And redefine them (4 times) whenever you resize/move a component?

Solution: component based screenshots

What if you could tell: “Take a screenshot of this div” instead of “Take a screenshot of this app and cut here, here and there”?

Even better: “Take a screenshot of this <insert your favorite UI framework> component”.

With PhantomJS, you can.


There are builds for Windows and MacOS X available on the download page, there is brew install phantomjs, there is a PPA for Ubuntu, and there are several git repositories.

I chose to compile it on my 32 bits Ubuntu computer:

sudo apt-get install libqt4-dev libqtwebkit-dev qt4-qmake
git clone git://github.com/ariya/phantomjs.git
cd phantomjs
git checkout 1.4.1

There is no install target in the Makefile so do whatever you usually do in this case (move/symlink the binary to /usr/bin/, add the bin/ directory in your $PATH, use the full path when invoking phantomjs…). The PhantomJS binary is bin/phantomjs.


phantomjs your_script.js [parameters]


You can find some examples on the site. Here are some of them:

Load a web page:

var page = new WebPage();
page.open(url, function (status) {
  // do something

Take a screenshot a a page:

var page = new WebPage(),
    address, output, size;
if (phantom.args.length < 2 || phantom.args.length > 3) {
    console.log('Usage: rasterize.js URL filename');
} else {
    address = phantom.args[0];
    output = phantom.args[1];
    page.viewportSize = { width: 600, height: 600 };
    page.open(address, function (status) {
        if (status !== 'success') {
            console.log('Unable to load the address!');
        } else {
            window.setTimeout(function () {
            }, 200);

Evaluate some JS code in the context of the web page:

var page = new WebPage();
page.open(url, function (status) {
    var title = page.evaluate(function () {
        return document.title;
    console.log('Page title is ' + title);

Combine of these possibilities and you have a nice screenshotting solution!

Component screenshotting

With PhantomJS, this is really simple:

  1. Load your app
  2. Find your divs / Find your components
  3. Get their bounding boxes (top, left, width, height)
  4. Render with clipRect

Example with an ExtJS demo app:

This is a RSS feed viewer and I want screenshots of:

  • The left panel
  • The preview button
  • The whole application, with the left panel collapsed

Here it is:

var page    = new WebPage(),
    address = 'http://dev.sencha.com/deploy/ext-4.0.7-gpl/examples/feed-viewer/feed-viewer.html';
page.viewportSize = {
    width  : 800,
    height : 600
// define the components we want to capture
var components = [{
    output : 'feed-viewer-left.png',
    //ExtJS has a nice component query engine
    selector : 'feedpanel'
    output : 'feed-viewer-preview-btn.png',
    selector : 'feeddetail > feedgrid > toolbar > cycle'
    output : 'feed-viewer-collapsed.png',
    //executed before the rendering
    before : function(){
        var panel = Ext.ComponentQuery.query('feedpanel')[0];
        panel.animCollapse = false; // cancel animation, no need to wait before capture
    selector : 'viewport'
page.open(address, function (status) {
    if (status !== 'success') {
        console.log('Unable to load the address!');
    } else {
         * give some time to ExtJS to
         *   - render the application
         *   - load asynchronous data
        window.setTimeout(function () {
                //execute the before function
                component.before && page.evaluate(component.before);
                // get the rectangular area to capture
                 * page.evaluate() is sandboxed
                 * so that 'component' is not defined.
                 * It should be possible to pass variables in phantomjs 1.5
                 * but for now, workaround!
                eval('function workaround(){ window.componentSelector = "' + component.selector + '";}')
                var rect = page.evaluate(function(){
                    // find the component
                    var comp = Ext.ComponentQuery.query(window.componentSelector)[0];
                    // get its bounding box
                    var box = comp.el.getBox();
                    // box is {x, y, width, height}
                    // we want {top, left, width, height}
                    box.top  = box.y;
                    box.left = box.x;
                    return box;
                page.clipRect = rect;
            // job done, exit
        }, 2000);


And here are the screenshots:



Now, we can automate screenshotting of specific components, even if we don’t know their position or size. Relaunch this script with your application in Spanish and voilà: 3 Spanish screenshots in 5 seconds, even if the button is bigger (or smaller, I don’t speak Spanish)!


  • Components to capture defined in the app itself
  • Browser extension/Bookmarlet to define the components to capture just by clicking on it
  • Use it for unit testing, with image comparison
  • Make a product of this, make profit

I hope you liked it!

[EN] Change Firebug’s own style

5 January, 2012 (15:48) | Notes, Webdev | Florian Cargoet


I recently switched to XFCE, using the NOX theme. Unfortunately, Firebug’s tabs use the same color as NOX’s background color.

grey text + grey background = invisible tabs!

This is extremely specific, nobody’s going to use it except me but I know I will need it whenever Firebug is updated.


Change Firebug!

$ mkdir myfirebug
$ cd myfirebug
$ unzip /path/to/firebug@software.joehewitt.com.xpi
$ vim skin/classic/win/firebug.css

Now, edit the color in the panelTab rule.

Zip everything and install it in Firefox.

$ cd myfirebug
$ zip -r custom-firebug@software.joehewitt.com.xpi *

[EN] My entry for the DailyJS “contest”

11 April, 2011 (23:45) | Webdev | Florian Cargoet

Last Friday, DailyJS had 5 digital subscriptions to Hacker Monthly to give away. They set up a small one-liner contest:

If you’d like to read more from Hacker Monthly, we’ve got 5 digital subscriptions to give away — worth $29 each! Just post a comment with your favourite JavaScript one-liner, and I’ll select 5 winners.

Thanks to this piece of code, I am the happy winner of one of the subscriptions:

(function ___(__){return function(_){return _!='?' && ___(__+_) || __+'!';};})('d')('a')('i')('l')('y')('j')('s')(' ')('r')('o')('c')('k')('s')('?')

In this article, I’ll explain what it does and how it works.
Lire la suite »

[EN] Ext.ux.KeySequenceMap

14 January, 2011 (21:37) | Ext JS | Florian Cargoet

Here is a useless extension I wrote for fun : Ext.ux.KeySequenceMap. As its name suggests, it’s based on Ext.KeyMap and it handles sequences of keys instead of unique keys.

Lire la suite »

[FR] Ext.ux.KeySequenceMap

14 January, 2011 (21:36) | Ext JS | Florian Cargoet

Voici une extension inutile (donc indispensable) que j’ai écrite pour m’amuser : Ext.ux.KeySequenceMap. Comme son nom l’indique, cette classe hérite de Ext.KeyMap et gère des séquences de touches plutôt que des touches uniques.

Lire la suite »

ExtJS EditorGridPanel, validation et accès au record dans le validator

14 March, 2010 (20:57) | Ext JS, Webdev | Florian Cargoet

Si vous n’avez jamais utilisé l’EditorGridPanel d’ExtJS, le titre peut paraitre un peu obscur donc je vais commencer par rappeler ce qu’est l’EditorGridPanel ainsi que les possibilités de validation offertes par ExtJS. Enfin, l’objet principal de cet article, nous verrons comment pousser un peu plus loin les possibilités du validator en lui donnant accès aux autres colonnes de l’EditorGridPanel.

Cet article mélange donc une introduction à l’EditorGridPanel, une présentation de quelques techniques de validation et une technique avancée pour aller plus loin. Il y en a donc pour tous les niveaux, faites le tri. Lire la suite »

ExtJS : Afficher un titre sur les régions “collapsed”

13 December, 2009 (01:50) | Ext JS, Notes | Florian Cargoet

Le border layout d’ExtJS est excellent mais souffre quand même d’un défaut important : les régions réduites  (collapsed) n’affichent plus aucune information ce qui empêche, par exemple, de les identifier. Il serait judicieux d’afficher au moins le titre du panel réduit afin de savoir à quoi correspond cette région “masquée”.

Pour visualiser un peu le problème, vous pouvez jeter un oeil à la démo du layout sur le site d’ExtJS et cliquer sur le bouton permettant de réduire la zone “South”.  Une fois réduit, le rectangle qui représente le panel réduit n’apporte pas beaucoup d’informations…

Pour accéder à ce rectangle et y insérer ce que vous voulez :

var component = Ext.getCmp(15);
var el = component.layout.south.collapsedEl;
el.insertHtml('afterBegin','&lt;span style="position: relative; top: 4px; left: 5px; color: #15428b; font-family: tahoma,arial,verdana,sans-serif; font-size: 11px; font-weight: bold;"&gt;Et voilà un titre&lt;/span&gt;');

Attention : l’élément collapsedEl n’existe qu’après la première réduction du panel donc il faut jouer avec l’évènement collapse.

ExtJS : changer le style d’un bouton dynamiquement

25 October, 2009 (23:32) | Ext JS, Webdev | Florian Cargoet

ExtJS est assez riche au niveau des boutons et permet de contrôler finement leur aspect à l’instanciation. Il est possible d’indiquer une icône (ou une classe qui mettra l’icône en background), d’ajouter un texte, de choisir si l’icône est à gauche, à droite, au dessus ou en dessous du texte. Les boutons peuvent avoir 3 tailles différentes (small, medium et large) et on peut associer un menu à un bouton ce qui se matérialise par une petite flèche sur le bouton que l’on choisit de placer à droite ou en dessous. Cela donne beaucoup de combinaisons possibles que vous pouvez voir en démo ici : http://www.extjs.com/deploy/dev/examples/button/buttons.html

Malheureusement, une fois ces superbes boutons créés, il n’est plus possible de modifier grand chose… Vous pouvez encore changer la classe qui met l’icône en background (unBouton.setIconClass(‘icon-class’); ) mais impossible de changer la taille du bouton, le placement de l’icône ou celui de la flèche du menu. De même, si un bouton n’a pas d’icône à la création, en ajouter une après coup va poser problème.

J’ai donc ajouté une petite méthode à la classe Ext.Button qui permet de changer tout ça même après la création des boutons ! Lire la suite »

Javascript : rendre une RegExp non sensible à la casse

14 October, 2009 (20:21) | Webdev | Florian Cargoet

Je n’ai pas trouvé de méthode idéale pour rendre une expression régulière existante non sensible à la casse. Il n’y a pas de méthodes pour ça sur les objets RegExp et la propriété ignoreCase est en lecture seule.

var regex = /blabla/;
regex.ignoreCase; //false
regex.ignoreCase = true;
regex.ignoreCase; //false encore...

Donc j’ai bidouillé un peu :

var regex = /blabla/;
regex.test('Blabla'); //false
regex = new RegExp(regex.toString().slice(1,-1), 'i');
regex.test('Blabla'); //true

Je trouve ça un peu lourd… Connaissez-vous une autre méthode ? Suis-je passé à côté de quelque chose ?

Extjs : les ajouts au prototype de Function

9 September, 2009 (22:31) | Ext JS, Webdev | Florian Cargoet

Si vous développez en Javascript, vous savez certainement que les objets ont un prototype et qu’on peut le modifier dynamiquement. On peut ainsi ajouter des fonctionnalités aux objets standards du Javascript (la librairie Prototype en fait d’ailleurs un usage intensif). Dans cet article, je vais me concentrer sur les ajouts fait par ExtJS à Function.

Lire la suite »