C’est avec plaisir que Xebia a hébergé le dernier ParisJS dans ses locaux le 30 janvier. Voici un compte-rendu de la soirée.
Marc Bourlon a ouvert cette 25ème édition de ParisJS avec la présentation d’une librairie qu’il a développée : TipTap.js (https://github.com/marcbourlon/TipTap). Il s’agit de la seule librairie JavaScript qui permette actuellement de déclencher des actions à partir d’une combinaision d’évenement "touch" ou "click". Ce type de librairie peut s’avérer très utile pour des applications web mobiles où l’espace disponible est précieux : au lieu de présenter à l’utilisateur toute une série de boutons, qu’il n’utilisera pas forcément, les fonctionnalités sont accessibles via une série de gestes. On retiendra l’exemple d’une application mobile de retouche de photo où on préfère afficher l’image en plein écran et proposer les fonctions de retouche à travers des "gestures".
La déclaration de ces combinaisons se fait de manière très simple :
TipTap.on( document.getElementById('myDiv'), { combo: 'tap', filter: '', callback: function(action) { alert("Tapped !"); } }, this );
La documentation est particulièrement soignée.
La soirée a continué par une démonstration de code en live et en TDD. François Zaninotto nous a présenté les user stories qu’il souhaitait développer. Il les a ensuite traduites en tests fonctionnels avec mocha et zombie.js (http://visionmedia.github.com/mocha/ et http://zombie.labnotes.org/) puis a développé ses fonctionnalités en nous présentant son workflow de développement bien rodé (voir son article de blog). Un exemple de test asynchrone avec une promesse q
it('should refuse empty submissions', function(done) { var browser = this.browser; browser.pressButton('Send').then(function() { assert.ok(browser.success); assert.equal(browser.text('h1'), 'Contact'); assert.equal(browser.text('div.alert'), 'Please fill in all the fields'); }).then(done, done); });
Le gist de ce test.
Nous avons ensuite eu le droit à une session de live coding en DART par Benoit Lemoine et Mathieu Breton. À travers le développement d’un jeu du "démineur" en 30 minutes. On a ainsi pu voir défiler les principales fonctionnalités de DART. Une présentation rythmée suivie d’une série de questions / réponses animée ! Le code de la session est disponible dans ce gist.
import "packages/unittest/unittest.dart"; import "minesweeper.dart"; main (){ group ("Minesweeper", (){ test ("Should be instantiable with with and height", (){ Minesweeper minesweeper = new Minesweeper (); expect (minesweeper.width, 0); expect (minesweeper.height, 0); }); Minesweeper minesweeper = new Minesweeper.fromGrid (""" 4 2 .*.. *... """); test ("Should be instantiable with a grid", (){ expect (minesweeper.width, 4); expect (minesweeper.height, 2); }); test("Should detect a bomb", () { expect(minesweeper.isBomb(0,0), false); expect(minesweeper.isBomb(1,0), true); expect(minesweeper.isBomb(-1,0), false); }); test("Should count the number of bomb", () { expect(minesweeper.countBomb(0,0),2); expect(minesweeper.countBomb(3,1),0); }); test("Should render correctly the grid", () { expect(minesweeper.solution, """ 2*10 *210 """); }); }); }
library minesweeper; class Minesweeper { int width; int height; List<String> _lines; Minesweeper (){ width = 0; height = 0; } Minesweeper.fromGrid(String grid) { var lines = grid.split('\n'); var dimensions = lines[0].split(' '); width = int.parse(dimensions[0]); height = int.parse(dimensions[1]); _lines = lines.getRange(1, lines.length -1); } bool isBomb (x, y){ if (x < 0 || x >= width || y < 0 || y >= height){ return false; } return _lines[y][x] == "*"; } int countBomb(x,y) { int result = 0; for(var xx = x -1 ; xx <= x+1; ++xx) { for(var yy = y -1 ; yy <= y+1; ++yy) { if(isBomb(xx, yy)) { result++; } } } return result; } String get solution { var result = ""; for (var y=0; y < height; y++){ for (var x=0; x < width; x++){ result = "$result${isBomb(x,y) ? "*" : countBomb(x,y)}"; } result = "$result\n"; } return result; } }
La soirée s’est terminée par la présentation par Xavier Bourry des possibilités de manipulation d’image via un élément <canvas> dans le navigateur. Sa démonstration est disponible en ligne (http://www.spacegoo.com/demos/parisjs/). À cette occasion, nous avons découvert notamment qu’une librairie peut s’avérer bien pratique: whammy.js, qui permet d’encoder à la volée une vidéo au format webM (la demo: http://antimatter15.github.com/whammy/clock.html):
var video = new Whammy.Video(15); video.add(context); var output = video.compile(); var url = (window.webkitURL || window.URL).createObjectURL(output);