@cjolif	

Etendre le Web avec les Web
Components
Christophe Jolif, @cjolif
IBM, http://github.com/ibm-js
JS Front End Open Source Dev Lead
@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 ?
@YourTwitterHandle	

#DVXFR14{session hashtag}	

 @cjolif
@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
@YourTwitterHandle	

#DVXFR14{session hashtag}	

 @cjolif
@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 });
@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
@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
@YourTwitterHandle	

#DVXFR14{session hashtag}	

 @cjolif
@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
@cjolif	

<super-calendar month="3" year="2014" view="month">
</super-calendar>
<button is="custom-button">My Button Text</button>
<c-devoxx country="France"></c-devoxx>
Concrètement ?
@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>
@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>
@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);
@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;
}
};
@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>
@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);
@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>
@YourTwitterHandle	

@cjolif
@YourTwitterHandle	

#DVXFR14{session hashtag}	

 @cjolif
@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
@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
@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
@YourTwitterHandle	

@cjolif
@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
@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)
@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>
@cjolif	

Delite - Concepts
• Le cycle de vie est le même:
• Mais enrichi:
createdCallback
attachedCallback
preCreate
buildRendering
postCreate
startup
destroy
@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:
});
});
@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, …
@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
@YourTwitterHandle	

@cjolif
@YourTwitterHandle	

#DVXFR14{session hashtag}	

 @cjolif
@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

Etendre le Web avec les Web Components

  • 1.
    @cjolif Etendre le Webavec les Web Components Christophe Jolif, @cjolif IBM, http://github.com/ibm-js JS Front End Open Source Dev Lead
  • 2.
    @cjolif Le plan devol • 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 ?
  • 3.
  • 4.
    @cjolif Le temps devol 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
  • 5.
  • 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
  • 9.
  • 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
  • 11.
    @cjolif <super-calendar month="3" year="2014"view="month"> </super-calendar> <button is="custom-button">My Button Text</button> <c-devoxx country="France"></c-devoxx> Concrètement ?
  • 12.
    @cjolif Templates • Extraits de codedestiné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 sespropres é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 plusimportant: 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 decacher 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 unbout 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>
  • 19.
  • 20.
  • 21.
    @cjolif L’atterrissage risque d’êtreun 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 quoien 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: – Polyfilldes 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
  • 24.
  • 25.
    @cjolif X-Tags • Librairies de « WebComponents » 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 • Fournirune 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 • LeWidget est un Custom Element classique <c-devoxx country="France"></c-devoxx> <script> document.querySelector("c-devoxx").setAttribute("country", "UK"); </script>
  • 28.
    @cjolif Delite - Concepts • Lecycle de vie est le même: • Mais enrichi: createdCallback attachedCallback preCreate buildRendering postCreate startup destroy
  • 29.
    @cjolif Delite - Concepts • Ladé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 • Lalibrairie 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 – Etencore • 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
  • 32.
  • 33.
  • 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