Etendre le Web ne se fait pas de manière cohérente aujourd'hui. Les Web Components résoudront ils se problème ? Comment commencer à utiliser les Web Components aujourd"hui, avec Polymer ou delite par exemple.
Web Components et Polymer 2 - GDG Algiers DevFest 2016 - 3 Décembre 2016
Etendre le Web avec les Web Components
1. @cjolif
Etendre le Web avec les Web
Components
Christophe Jolif, @cjolif
IBM, http://github.com/ibm-js
JS Front End Open Source Dev Lead
2. @cjolif
Le plan de vol
• Le temps de vol sera de 45 mins, objectifs ?
• Mélanger et adapter, pas toujours facile
• Les « Web Components », c’est quoi ?
• Et je fais quoi en attendant l’atterrissage ?
• Quelques questions avant le débarquement ?
4. @cjolif
Le temps de vol sera de 45 mins, objectif ?
• Etendre le Web:
– Utiliser des composants plus avancés que ceux fournis
par HTML5
– Créer ses propres composants
• Comprendre que les difficultés rencontrées aujourd’hui
pour étendre le Web ne sont pas « normales »
• Entrevoir les solutions standards qui nous sont proposées
pour le futur
• Commencer a expérimenter / utiliser ces solutions
aujourd’hui
6. @cjolif
Mélanger et adapter, pas toujours facile
• Les composants s'utilisent de manières différentes d'une
librairie à l'autre (déclaratif, programmatique):
<div data-dojo-type=“dojox/mobile/Slider”
data-dojo-props=“value: 4”></div>
<script>
require(["dojox/mobile/Slider", "dojo/query"],
function (Slider, query) { new Slider({value: 4}, query("#slider")); });
</script>
<ul data-role="listview"></ul>
<script src="ratingPlugin.js"></script>
$(“#rating”).ratingPlugin({value: 4 });
7. @cjolif
Mélanger et adapter, pas toujours facile
• Les composants se définissent de façon différentes avec
un cycle de vie différent et plus ou moins complet
• jQuery plugin: juste une fonction
• Dojo widget: dijit/_WidgetBase
– buildRendering, postCreate, startup, destroy
• jQuery Mobile: non extensible directement
• jQuery UI: $.widget
– _create, _init, _destroy
8. @cjolif
Mélanger et adapter, pas toujours facile
• Chaque boîte à outils de composants possède sa propre
façon de:
– Définir son composant, syntaxe mais surtout son propre
cycle de vie
– Utiliser son composant, syntaxe, paradigme
programmatique ou déclaratif
• Chaque boîte à outils applicative possède sa propre
façon d’assembler et de lier les composants entre eux
10. @cjolif
Les « Web Components », c’est quoi ?
• Tous les composants dont on vient de parler pourraient être
des « Web Components »
• En fait, sous ce terme on regroupe plutôt les composants
appliquant ou utilisant un sous-ensemble de
spécifications W3C:
– Templates
– Custom Elements
– Shadow DOM
– HTML Imports
• Arrière-petites-filles de XUL, XBL1 et petites-filles de XBL2
12. @cjolif
Templates
• Extraits de code destinés à être utilisés "plus tard",
éventuellement plusieurs fois
• Initialement analysé mais pas rendu
• N'est pas directement accessible par le document
<template id="devoxxtemplate">
Devoxx <span id="country"></span>
<img src="">
</template>
13. @cjolif
Templates
• Accessible à travers « content »:
<template id="devoxxtemplate">
Devoxx <span id="country"></span>
<img src="">
</template>
<script>
var t = document.querySelector("#devoxxtemplate");
var instance = t.content.cloneNode(true);
instance.querySelector("#country").innerHTML = "France";
instance.querySelector("img").src = "France.png";
document.body.appendChild(instance);
</script>
14. @cjolif
Custom Elements
• Créer ses propres éléments HTML et les enregistrer avec
la méthode document.registerElement:
• La balise doit contenir un tiret pour être valide (-)
var proto = Object.create(HTMLElement.prototype);
proto.swapimage = function () { … };
var Devoxx = document.registerElement("c-devoxx",
{ /*extends: "button", */ prototype: proto});
var devoxx = new Devoxx();
devoxx.addEventListener("click",
function (event) { event.currentTarget.swapimage(); }
);
parent.appendChild(devoxx);
15. @cjolif
Custom Elements
• Définition à travers les méthodes du cycle de vie:
proto.createdCallback = function () {
var t = document.querySelector("#devoxxtemplate");
var instance = t.content.cloneNode(true);
instance.querySelector("#country").innerHTML =
this.getAttribute("country");
// …
this.appendChild(instance);
};
proto.attachedCallback = …; proto.detachedCallback = …;
proto.attributeChangedCallback = function (name, oldValue, newValue) {
if (name === "country") {
this.querySelector("#country").innerHTML = newValue;
}
};
16. @cjolif
Custom Elements
• Le plus important: utilisation comme n'importe quel
élément HTML !
<c-devoxx country="France"></c-devoxx>
<script>
document.querySelector("c-devoxx").setAttribute("country", "UK");
</script>
17. @cjolif
Shadow DOM
• Permet de cacher l'implémentation du composant (sa
structure DOM interne) de l'utilisateur
• Par défaut permet d'assurer que le style d'un bout de
DOM n'est pas atteint par le style de la page
• Typiquement utilisé dans un Custom Element pour
contenir le rendu de cet élément, souvent crée à partir
d'un template
var root = element.createShadowRoot()
root.appendChild(instance);
18. @cjolif
HTML Imports
• Importer un bout de HTML (possiblement un "Web
Component") dans un autre bout de HTML
• Gère la hiérarchie des dépendances pour vous
<link rel="import" href="c-devoxx.html">
<c-devoxx country="France"></c-devoxx>
<link rel="import" href="c-conference.html">
<element name="c-devoxx">
<template>
…
</template>
</element>
21. @cjolif
L’atterrissage risque d’être un peu rude
• Les APIs sont encore changeantes enterView -> attach
• Custom Elements: Chrome >= 33
=> Personne d’autre (sauf Firefox « nightly »)
• Shadow DOM: Chrome >= 25, Android >= 4.4 (avec prefix)
=> très bientôt: Firefox >= 29
=> Pas de IE, Safari/iOS, Android < 4.4, Firefox ESR 24
• Templates: Firefox >= 26, Chrome >= 36, Android >= 4.4
=> Pas de IE, Safari/iOS, Android < 4.4, Firefox ESR 24
• Import: Pas d’implémentation
22. @cjolif
Je fais quoi en attendant ?
• J’utilise un / des polyfills quand cela a du sens
• Cela a du sens si :
– Je commence/investigue un développement pour 2015
– Cela résout un de mes problèmes
– Cela ne pénalise pas outre mesure les performances
sur mes plateformes cibles
23. @cjolif
Polymer
• http://www.polymer-project.org/ (Google)
• Polymer Platform:
– Polyfill des 4 spécifications « Web Components »
– Polyfill d’autres spécifications comme: pointer events,
Mutation Observer…
• Polymer Core: promeut sa propre solution de binding sur
template (TemplateBinding anciennement MDV)
– Permet de souvent se débarrasser de attributeChanged
• Cible les plateformes récentes uniquement (pas de Android <
4.4, pas de IE9, …) peut-être très limitant
25. @cjolif
X-Tags
• Librairies de « Web Components » basé sur Custom
Element et HTML Imports
– http://www.x-tags.org/ (Mozilla)
• Utilise Polymer mais ajoute la compatibilité IE9
• Fournit des services supplémentaires sur les Custom
Elements:
– Mixins
– Events
26. @cjolif
Delite - Objectifs
• Fournir une infrastructure de Widget basée sur les Web
Components
– https://github.com/ibm-js/delite (Dojo Foundation, IBM)
• Se reposer sur les implémentations natives ou Polymer quand
présentes
• Fournir un bon compromis entre la taille de code, les
performances, les browsers supportés (IE9, Android 4.0+), les
fonctionnalités fournies et l’adoption des Web Components
• Ne pas se précipiter sur les fonctionnalités non nécessaires et
potentiellement remise en cause (cf Apple vs Google sur le
shadow DOM)
27. @cjolif
Delite - Concepts
• Le Widget est un Custom Element classique
<c-devoxx country="France"></c-devoxx>
<script>
document.querySelector("c-devoxx").setAttribute("country", "UK");
</script>
28. @cjolif
Delite - Concepts
• Le cycle de vie est le même:
• Mais enrichi:
createdCallback
attachedCallback
preCreate
buildRendering
postCreate
startup
destroy
29. @cjolif
Delite - Concepts
• La définition est centrée sur le JavaScript et AMD est utilisé
pour le chargement des modules y compris le CSS et le
template:
• Mais « sous la capot » cela utilise la même API
registerElement
define([ , "delite/register",
, ],
function ( , register, ) {
return register("c-devoxx", [HTMLElement, ], {
buildRendering:
});
});
30. @cjolif
Delite - Concepts
• La librairie fournie de nombreux autres utilitaires:
- Comment x-tags: déclaration des événements, possibilité
de mixins
- Mais aussi: facilités de connections au données, de
gestion de la sélection, de gestion de l'invalidation des
propriétés, …
31. @cjolif
Delite – Et encore
• Générer vos propre Web Components basé sur delite
avec Yeoman:
- http://github.com/cjolif/generator-delite-element
• Deliteful est une librairies de widget basés sur delite en
cours développement:
– https://github.com/ibm-js/deliteful
34. @cjolif
Crédit image / Creative Commons
• Rue pavée — By-Nc-Sa
• http://www.flickr.com/photos/22914687@N05/4957591422/sizes/l/
• Sous la Tour Eiffel — By-Nc-Sa
• http://www.flickr.com/photos/stewiedewie/244850735/sizes/l/in/photostream/
• Sous le pont — photo par B.Monginoux - By-Nc-Nd
• http://www.landscape-photo.net/displayimage.php?pid=5194
• Le Louvre – Photo par Anthony Gaudun - By-Nc-Sa
• http://www.flickr.com/photos/anthonygaudun/7474397964/sizes/o/in/photostream/
• Mystère, mystère…, Fin de journée sur la Seine – Christophe Jolif
• Slide template created by @glaforge, completed by @nmartignole for Devoxx FR2014