Les Web Components ont pris une nouvelle ampleur depuis le dernier Google I/O. Déjà à la base du framework Dart WebUi (renommé depuis en Polymer.Dart), Google a (re)dévoilé un projet polyfill pour la spécification des Web Components, Polymer, et a dans le même temps annoncé son utilisation prochaine dans AngularJS.
La spécification Web Components
La spécification des Web Components, encore en cours de fabrication dans les usines du W3C, est destinée à standardiser des notions comme le templating, l'encapsulation, les éléments DOM personnalisés... afin de permettre de les utiliser nativement au sein de nos navigateurs, quel que soit le framework utilisé. Cette spécification s'inscrit également dans la mouvance "Declarative over Imperative" ou "The Declarative Renaissance", mise en avant notamment par le framework AngularJS.
Mais comme toute spécificaton, celle-ci prend du temps, pour être discutée, pour être implémentée... C'est pourquoi, à l'instar de ce que propose WebShims pour émuler les fonctionnalités HTML5, plusieurs polyfills commencent à apparaître pour les Web Components. Un polyfill est tout simplement une bibliothèque JavaScript destinée à émuler des fonctionnalités qui ne sont pas encore implémentées dans les navigateurs. Lorsqu'une fonctionnalité est absente, elle est émulée en JavaScript par le polyfill.
Les deux principaux polyfills sont issus de deux des principaux acteurs du web, Mozilla et Google.
X-Tag, par Mozilla
X-Tag est une bibliothèque JavaScript Open Source qui émule uniquement la partie "Custom Elements". Elle permet d'enregistrer ses propres éléments pour pouvoir ensuite les utiliser directement dans le DOM. Par exemple, on peut utiliser le code suivant :
<x-map data-key="6c86bb5b30a442c180772d978f3ae000"></x-map>
Pour afficher la carte suivante :
<x-map>
fait partie des éléments fournis par défaut avec X-Tag. Il est bien évidemment possible d'enregistrer ses propres éléments.
xtag.register('x-superinput', {
...
});
En second paramètre, la méthode register prend un objet permettant de customiser entièrement le comportement de notre composant, ajouter des callbacks sur son cycle de vie, se binder sur des événements.
xtag.register('accordion', {
lifecycle:{
created: function(){
// lancé une fois lorsque l'élément est initialement créé ou parsé
},
inserted: function(){
// lancé chaque fois que l'élément est inséré dans le DOM
},
removed: function(){
// lancé chaque fois que l'élément est supprimé du DOM
},
attributeChanged: function(){
// lancé lorsque les attributs sont modifiés
}
},
events: {
'click:delegate(x-toggler)': function(){
// active un toggle de type clic
}
},
accessors: {
'togglers': {
get: function(){
// retourne tous les toggles fils
},
set: function(value){
// faire quelque chose
}
}
},
methods: {
nextToggler: function(){
// active le toggle suivant
},
previousToggler: function(){
// active le toggle précédent
}
}
});
Pour avoir un aperçu des possibilité de X-tag, Mozilla fournit également le projet Brick qui regroupe un ensemble de composants (calendar, deck, tooltip...) construits au dessus de X-Tag.
Polymer, par Google
Polymer est un nouveau type de bibliothèque pour le Web, bâti au-dessus des Web Components, et conçu pour tirer parti des évolutions du Web sur les navigateurs modernes.
Le projet Polymer, anciennement Toolkitchen et plus anciennement encore MDV, est donc l'un des petits derniers de la famille Google. Il permet de bénéficier de la spécification Web Components, mais pas seulement.
Les principales spécifications émulées sont :
- HTML Imports
- Custom Elements
- Shadow DOM
- Pointer Events
- Web Animations
- Mutation Observers
On trouve également le Template binding et Node.bind().
Comme on peut le voir sur ce schéma, Polymer est décomposé en plusieurs composants :
- Foundation (avec le fichier platform.js) est l'API de bas-niveau qui émule les fonctionnalités décrites précédemment
- Core (polymer.js) fournit une abstraction de la couche Foundation. C'est notamment grâce à cette abstraction que l'on va simplement pouvoir créer ses éléments Custom
- Enfin, par dessus ces deux couches "techniques", on va pouvoir retrouver un ensemble d'éléments fournis par défaut.
HTML Imports, Custom Elements & Shadow DOM
Les imports HTML sont une façon d'inclure et de réutiliser des documents HTML dans d'autres documents HTML.
Voici un exemple très simple d'import HTML
<link rel="import" href="import-file.html">
Les imports vont notamment nous permettre d'intégrer des documents HTML contenant des éléments personnalisés du DOM dans d'autres documents HTML.
Les éléments personnalisés permettent aux auteurs de définir et d'utiliser de nouveaux types d'éléments du DOM dans un document HTML.
Comme par exemple avec l'élément <x-map>
mentionné dans l'exemple précédent avec X-Tag.
Et enfin le Shadow DOM...
Le Shadow DOM est conçu pour fournir une encapsulation en masquant des sous-arbres du DOM sous des Shadow Root, des noeuds racines masqués dans le DOM. Il fournit une méthode pour établir et maintenir des barrières fonctionnelles entre les arbres DOM, et la façon dont ces arbres interagissent entre-eux au sein d'un document, permettant ainsi une meilleure encapsulation fonctionnelle dans le DOM.
Des articles allant de l'introduction pour les novices jusqu'à l'utilisation de l'API pour les plus avancés sont disponibles sur le site HTML5 Rocks.
Voici un exemple simple de création d'un élément custom avec Polymer
<polymer-element name="custom-element" noscript>
<template>
<p>Bonjour je suis {{name}}.
J'ai {{age}} ans.</p>
<label for="ageInput">Age :</label>
<input id="ageInput" type="range" value="{{age}}"><br />
<label for="nameInput">Nom :</label>
<input id="nameInput" value="{{name}}" placeholder="Votre nom ici...">
</template>
<script>
Polymer('custom-element', {
age: 26,
name: "Julien",
});
</script>
</polymer-element>
Et comment l'importer simplement dans un autre document HTML
<!DOCTYPE html>
<html>
<head>
<script src="polymer.min.js"></script>
<link rel="import" href="custom-element.html">
</head>
<body>
<custom-element></custom-element>
</body>
</html>
Le résultat est le suivant avec, à remarquer, le databinding entre les deux inputs (text et range) et le texte affiché au-dessus dans le DOM.
La solution se rélève très propre, et a pour principal avantage d'être portable. En effet, vous pouvez utiliser ce composant dans des pages HTML construites avec des frameworks différents, qu'il s'agisse de frameworks JavaScript tels que AngularJS, Backbone... ou de frameworks avec construction des pages côté serveur tels que JSF.
Web Animations & Pointer Events
Les Web Animations, comme leur nom l'indique, vont nous permettre de simplifier la gestion des animations, en plus des spécifications CSS déjà existantes.
De leur côté, les Pointer Events permettent de gérer des évènements d'entrée de façon agnostique qu'il s'agisse d'une souris, d'un stylet ou d'un écran tactile.
Et ensuite ?
Ensuite, il va falloir commencer à utiliser Polymer dans nos applications. Et pour cela, c'est sûrement AngularJS qui a pris le plus d'avance. Tout d'abord dans le coeur du framework, en commençant à étudier les spécifications Object.Observe() et les mutations observers.
Ensuite en étudiant la possibilité de remplacer les directives AngularJS par des éléments Custom des Web Components. Plus d'infos à ce sujet sur la news InfoQ, Que sait-on sur Angular JS 1.2 et 2.0 ?