Introduction aux Web components (DNG Consulting)

39
Web Components Révolutionnez votre HTML avec les web components DNG Consulting http://www.dng-consulting.com V2.5

Transcript of Introduction aux Web components (DNG Consulting)

Page 1: Introduction aux Web components (DNG Consulting)

Web Components Révolutionnez votre HTML avec les web components

DNG Consulting http://www.dng-consulting.com

V2.5

Page 2: Introduction aux Web components (DNG Consulting)

Introduction

Intérêt

Enrichir le Web avec de nouveaux tags

- Le standard HTML compte une centaine de balises seulement

Aider à la réutilisation de code – éviter le copier-coller

Principes

Créer de nouvelles balises

Encapsuler le code afin de masquer et isoler sa complexité

Pouvoir importer et déclarer les balises dans d’autres projets/pages

2

Page 3: Introduction aux Web components (DNG Consulting)

Introduction - Historique

Initié par Google depuis 2010 avec le projet Polymer,

relayé par Mozilla et d’autres acteurs du web

Basé sur des standards en cours au W3C

Chrome 36 premier navigateur compatible

La technologie « Polyfill » pour les navigateurs plus

anciens

Librairie webcomponents.js remplaçant platform.js (depuis fin 2014,

avec le transfert de la librairie de Polymer vers WebComponents.org)

3

Page 4: Introduction aux Web components (DNG Consulting)

4 normes à la base de WebComponent

4

Ecosystème HTML5

Custom element

HTML Template

Shadow DOM

HTML import

Polyfill

importer webcomponents.js

Framework facilitant la création de

Web Component

Polymer

X-Tag

Bosonic

Page 5: Introduction aux Web components (DNG Consulting)

DÉFINIR UN WEB COMPONENT

5

Page 6: Introduction aux Web components (DNG Consulting)

Introduction

Qu’est-ce qu’un Web Component ?

Identifier les technologies permettant leur création

Il faut pouvoir

définir de nouvelles balises

ajouter du contenu

encapsuler sa définition

réutiliser les composants

6

Page 7: Introduction aux Web components (DNG Consulting)

7

Source http://webcomponents.org/

• Chrome: implémenté

• Opera: implémenté

• Firefox: en cours de dev.

• Safari: non implémenté

• IE: en cours de considération

Spécification Custom Elements

Page 8: Introduction aux Web components (DNG Consulting)

Custom Element - principes

Permet de définir nos propres balises HTML

Peut avoir un rendu ou non

Contient du code et/ou du contenu HTML

Pour le créer:

tag-name est le nom de la balise. Doit contenir au moins un ‘-’

options sont principalement le prototype et extend

retourne le constructeur qui permet d’instancier la balise

Et <element></element> ?

La spécification n’a jamais aboutie et semble être délaissée depuis août

2013 8

var constructor = document.registerElement(tag-name, options);

Page 9: Introduction aux Web components (DNG Consulting)

Custom Element – Déclaration

Instancier un Custom Element

De manière déclarative – la plus élégante

Dans le code via le constructeur

Dans le code via document.createElement() – la plus classique en JS

9

var MyComponent = document.registerElement(‘mon-composant');

var dom = new MyComponent();

document.body.appendChild(dom);

<script> document.registerElement(‘mon-composant'); </script>

<mon-composant></mon-composant>

document.registerElement(‘mon-composant');

var dom = document.createElement(‘mon-composant');

document.body.appendChild(dom);

Page 10: Introduction aux Web components (DNG Consulting)

Custom Element – Comportement

Ajouter des comportements

Utilisation de l’argument options

Créer un prototype dérivant de HTMLElement

Définir les nouveaux comportements à partir de ce prototype

- Attributs

- fonctions

10

document.registerElement(tag-name, options);

Page 11: Introduction aux Web components (DNG Consulting)

Custom Element – Comportement

Exemple de code:

11

var proto = Object.create(HTMLElement.prototype);

proto.nom = ‘Mon Composant';

proto.afficheNom = function() {

console.log(‘Nom de la balise : ' + this.nom);

};

document.registerElement(‘mon-composant', {prototype: proto });

var dom = document.createElement(‘mon-composant’);

Page 12: Introduction aux Web components (DNG Consulting)

Custom Element – Héritage

Hériter d’une balise HTML existante

déclarer dans options de registerElement() avec mot clé extends

dériver du prototype de l’élément HTML hérité

Utilisation

12

document.registerElement(‘mon-champs-saisie', {

extends: 'input',

prototype: Object.create(HTMLInputElement.prototype)

});

Doivent correspondre

<input is=“mon-champs-saisie”></input>

Page 13: Introduction aux Web components (DNG Consulting)

Custom Element – Cycle de vie

Des callbacks sur prototype pour nous aider à définir

notre Custom Element

createdCallback() appelé après la creation de l’élément

attachedCallback() appelé lors de l’attachement au DOM

detachedCallback() appelé lors du détachement au DOM

attributeChangedCallback() appelé lors d’un changement attribut

Exemple

13

var proto = Object.create(HTMLElement.prototype);

proto.createdCallback = function() {

var div = document.createElement('div');

div.textContent = ‘Le contenu de mon composant';

this.appendChild(div);

};

document.registerElement(‘mon-composant', {prototype: proto)});

<mon-composant>

<div>Le contenu de mon composant</div>

</mon-composant>

Page 14: Introduction aux Web components (DNG Consulting)

Custom Element – Exemple

14

var proto = Object.create(HTMLElement.prototype);

proto.createdCallback = function() {

this.innerHTML = "<style>.outer { border: 2px solid #347fac; border-radius: 1em; background: #347fac; font-size: 20pt;

width: 12em; height: 7em; text-align: center;}.title {color: white; font-family: sans-serif; padding: 0.5em;}.name {color:

black; background: white; font-size: 45pt; padding-top: 0.2em;} </style><b>Je suis un badge DNG</b><div

class='outer'><div class='title'></div><div class='name'></div></div>";

};

proto.attachedCallback = function(){

var self = this;

var b= document.querySelector("b");

b.addEventListener('click', function(ev) {

var event = new CustomEvent(‘click-title', { 'detail': ev });

self.dispatchEvent(event);

});

var titleDiv= document.querySelector(".title");

titleDiv.innerHTML = this.getAttribute("label");

var nameDiv= document.querySelector(".name");

nameDiv.innerHTML = this.getAttribute("nom");

};

document.registerElement(‘dng-badge', {prototype: proto});

<dng-badge label="Badge de:" nom="ZOE"/>

<script>

var dom = document.querySelector('dng-badge');

dom.addEventListener(‘click-title', function(e) {

alert('Clique sur le titre');

});

</script>

Page 15: Introduction aux Web components (DNG Consulting)

Custom Element – Conclusion

Custom Element permet de créer ses propres balises

HTML

Mixer des balises HTML dans des chaînes de caractères

(innerHTML) n’est pas une solution très viable pour des

interfaces complexes

15

Page 16: Introduction aux Web components (DNG Consulting)

HTML Template pour aider à la

création d’interface

16

Source http://webcomponents.org/

• Chrome: implémenté

• Opera: implémenté

• Firefox: implémenté

• Safari: implémenté

• IE: en cours de considération

Page 17: Introduction aux Web components (DNG Consulting)

HTML Template - Principe

Avoir un format prédéfini réutilisable

Ne pas avoir à recréer le même cadre à chaque fois

Concept existant dans le web, mais côté serveur comme

Apache Velocity en Java

Django en Python

Smarty en PHP

Et bien d’autres…

Peu de solutions côté client (exécuté dans le navigateur)

17

Page 18: Introduction aux Web components (DNG Consulting)

HTML Template - Principe

Une déclaration simple en utilisant les balises

<template>…</template>

Caractéristiques de cet élément

Son contenu n’est pas visible par le moteur de rendu du navigateur

Les scripts ne s’exécutent pas, les images ne sont pas chargées, …

Le contenu n’est pas considéré comme attaché au DOM

(document.getElementById() ou querySelector() ne fonctionnent pas)

Il peut être placé n’importe où dans la page HTML

Activer un template

18

var t = document.querySelector(‘template’);

var clone = document.importNode(t.content, true);

document.body.appendChild(clone);

Page 19: Introduction aux Web components (DNG Consulting)

HTML Template – exemple

19

<template id="badgeTemplate">

<link href="templateBadge.css" rel="stylesheet">

<b>Je suis un badge DNG</b>

<div class='outer'>

<div class='title'></div>

<div class='name'></div>

</div>

<script>

var b= document.querySelector("b");

b.addEventListener('click', function(ev) {

alert("clique sur le titre !");

});

alert("Template actif");

</script>

</template>

<script>

var content = document.querySelector('#badgeTemplate').content;

content.querySelector(".title").innerHTML = "Badge de:";

content.querySelector(".name").innerHTML = "ZOE";

document.body.appendChild(document.importNode(content, true));

</script>

templateBadge.css

.outer {

border: 2px solid #347fac;

border-radius: 1em;

background: #347fac;

font-size: 20pt;

width: 12em;

height: 7em;

text-align: center;

}

.title {

color: white;

font-family: sans-serif;

padding: 0.5em;

}

.name {

color: black;

background: white;

font-size: 45pt;

padding-top: 0.2em;

}

Exemple de script en utilisant la spécification Template

Page 20: Introduction aux Web components (DNG Consulting)

20

<script>

var proto = Object.create(HTMLElement.prototype);

proto.createdCallback = function() {

var content = document.querySelector('#badgeTemplate').content;

this.appendChild(document.importNode(content, true));

};

proto.attachedCallback = function(){

var self = this;

var b= document.querySelector("b");

b.addEventListener('click', function(ev) {

var event = new CustomEvent(‘click-title', { 'detail': ev });

self.dispatchEvent(event);

});

var titleDiv= document.querySelector(".title");

titleDiv.innerHTML = this.getAttribute("label");

var nameDiv= document.querySelector(".name");

nameDiv.innerHTML = this.getAttribute("nom");

};

document.registerElement(‘dng-badge', {prototype: proto});

<script>

<dng-badge label="Badge de:" nom="ZOE"/>

<script>

var dom = document.querySelector('dng-badge');

dom.addEventListener(‘click-title', function(e) {

alert('Click sur le titre');

});

</script>

HTML Template – Custom Element

Script modifié pour

une utilisation via les

Web Component

Page 21: Introduction aux Web components (DNG Consulting)

HTML Template – Conclusion

HTMLTemplate facilite la création graphique des Custom

Element

Déclaration à l’aide de balise simple à lire et à maintenir

les ressources déclarées dans le template sont inactives tant qu’on ne

l’instancie pas.

Comment s’assurer que ce que l’on déclare dans le

template s’affichera comme il a été défini?

Concurrence des styles CSS, …

Peut-on aller plus loin dans la séparation présentation et

données ?

Peut-on imaginer du databinding ?

21

Page 22: Introduction aux Web components (DNG Consulting)

Object.observe() pour le

databinding

22

• Chrome: implémenté

• Opera: implémenté

• Firefox: non implémenté.

• Safari: non implémenté

• IE: en cours de considération

Page 23: Introduction aux Web components (DNG Consulting)

Object.observe() pour le databinding

Principe: être notifié nativement lors d’un changement

sur un objet JavaScript

Standard prévu pour ECMAScript 7

20 à 40 fois plus rapide qu’une bibliothèque tierce

Benchmark AngularJS en 2012, 40 ms pour une mise à jour alors que

Object.observe() met 1-2 ms pour la même.

Intérêts:

Séparation des couches Modèle et Vue

Les notifications sont asynchrones

23

Page 24: Introduction aux Web components (DNG Consulting)

Object.observe() – Principe

Ajouter un handler pour tous les changements d’un objet

Considérons l’exemple suivant

On a un modèle, on définit un handler et on lie le handler aux

changements du modèle avec Object.observe()

Pour arrêter l’écoute: 24

var model = {name: ‘ZOE’, sex: ‘Female’, color: ‘blue’}

function handler(changes){

changes.forEach(function(change, i) {

console.log('propriété modifiée: ' + change.name);

console.log('nature du changement: ' + change.type);

console.log(‘nouvelle valeur: ' + change.object[change.name]); });

}

Object.observe(model, handler);

Object.observe(model_a_observer, observer);

Object.unobserve(model_a_observer, observer);

Page 25: Introduction aux Web components (DNG Consulting)

Object.observe() – Principe

Exemple d’événements

25

Modification

Logs de la console:

Page 26: Introduction aux Web components (DNG Consulting)

Object.observe() – Et encore plus…

Possibilité d’observer les Tableau

Obtenir les changements en cours tout de suite

Créer ses propres notifications groupées

Ne pas être notifié unitairement mais pour un ensemble défini.

Utile pour les modèles avec énormément de données (cas de grosses

applications)

- Type_creer: le nom du type de changement qui sera notifié (et à écouter)

- Action: une fonction contenant les actions de modifications faites avant la

notification. Peut renvoyer un objet dont les champs seront ajoutés à l’objet

change

26

Object.getNotifier(model).performChange(type_creer, action);

Array. observe(model_a_observer, observer);

Object.deliverChangeRecords(observer);

Page 27: Introduction aux Web components (DNG Consulting)

Shadow DOM pour

l’encapsulation

27

Source http://webcomponents.org/

• Chrome: implémenté

• Opera: implémenté

• Firefox: en cours de dev.

• Safari: non implémenté

• IE: en cours de considération

Page 28: Introduction aux Web components (DNG Consulting)

Shadow DOM - Principes

Shadow DOM permet de séparer le contenu de la

présentation tout en éliminant les conflits de noms

Permet de cacher toute la cuisine interne d’un composant

Permet d’encapsuler les styles naturellement

Principe

Créer un shadow DOM sur un élément HTML comme un Div

Ajouter du contenu

28

<style> p { color: Green; } </style>

<p>Du texte dans ma page html</p>

<div id="element"></div>

<script>

var foo = document.getElementById('element');

foo.createShadowRoot();

var p = document.createElement('p');

foo.shadowRoot.appendChild(p);

p.textContent = 'Du texte dans le shadow DOM';

</script>

Page 29: Introduction aux Web components (DNG Consulting)

Shadow DOM - Content

La présentation est masquée dans le Shadow DOM

Il faut pouvoir définir et insérer du contenu

La balise <content> permet d’identifier des points d’insertion

Le texte mis entre les balises sera inséré en lieu et place de <content>

29

<style> p { color: Green; } </style>

<p>Du texte dans ma page html</p>

<div id="element">ZOE</div>

<script>

var foo = document.getElementById('element');

foo.createShadowRoot();

var p = document.createElement('p');

foo.shadowRoot.appendChild(p);

p.innerHTML = ‘Mon nom est : <content/>';

</script>

Page 30: Introduction aux Web components (DNG Consulting)

Shadow DOM – Content – plus loin

Possibilité de différentier les contenus

Les balises content peuvent être différenciées avec l’attribut select

select correspond au nom d’une balise, un ID ou même la classe CSS

Pas d’attribut select correspond au texte par défaut (sans balise)

Si plusieurs content identiques, seule la première est utilisée

Plusieurs balises identiques, leurs contenus seront ajoutés l’un après

l’autre à la place du content correspondant

30

<style> p { color: Green; } </style>

<p>Du texte dans ma page html</p>

<div id="element">ZOE <nom>Hochedez</nom> Cindy</div>

<script>

var foo = document.getElementById('element');

foo.createShadowRoot();

var p = document.createElement('p');

foo.shadowRoot.appendChild(p);

p.innerHTML = ‘’Mon nom est : <content select=‘nom’/><content/>’’;

</script>

Page 31: Introduction aux Web components (DNG Consulting)

Shadow DOM pour les Web Components

Quel intérêt pour nos Web Components ?

Utilisé directement sur le Custom Element, il permet de masquer la

complexité du composant

Les styles de la nouvelle balise ne seront pas en conflit avec d’autres

utilisations de Template

En reprenant l’exemple vu dans le chapitre Template

Le code commenté est la version précédente

31

proto.createdCallback = function() {

//var content = document.querySelector('#badgeTemplate').content;

//this.appendChild(document.importNode(content, true));

var shadow = this.createShadowRoot();

var content = document.querySelector('#badgeTemplate').content;

shadow.appendChild(document.importNode(content, true));

};

Page 32: Introduction aux Web components (DNG Consulting)

HTML Import pour réutiliser ses

Web Components

32

Source http://webcomponents.org/

• Chrome: implémenté

• Opera: implémenté

• Firefox: en cours de dev.

• Safari: non implémenté

• IE: en cours de considération

Page 33: Introduction aux Web components (DNG Consulting)

HTML import - Introduction

Custom Element, HTML Template et Shadow DOM

permettent de créer des Web Components, comment les

réutiliser?

On peut actuellement charger les éléments JS, CSS et

HTML séparément

Imaginez la complexité si vous importez des Web

Components qui utilisent eux aussi d’autres Web

Components

Ou utiliser une iframe, ou encore du code JS… Pas très

élégant

33

Page 34: Introduction aux Web components (DNG Consulting)

HTML import - Principe

Nouvelle définition de la balise link

Permet d’importer le contenu de monComposant

href contient le chemin vers le fichier html

HTML import va charger le document HTML, résoudre le

chargement des sous-ressources et exécuter le code

JavaScript.

Le contenu n’est pas affiché automatiquement à l’endroit de l’import

Du code doit être écrit pour réaliser cet affichage

Les balises de rendu ne sont pas ajoutées au DOM, mais les balises

style, script, link sont bien exécutées.

34

<link rel=‘import’ href=‘monComposant.html’>

Page 35: Introduction aux Web components (DNG Consulting)

HTML import - règles

Le fichier HTML importé

peut charger des ressources comme des scripts, css, images…

peut ne pas déclarer de balises html, head, body, doctype.

Plusieurs import HTML faisant référence à la même URL

ne sera importé et exécuté qu’une seule fois

Les restrictions Cross-domain s’appliquent

voir CORS (Cross Origin Resource Sharing) si besoin

Possibilité de gérer les erreurs de chargements

35

<link rel=‘import’ href=‘monComposant.html’

onload=‘handleLoad(event)’

onerror=‘handleError(event)’>

Page 36: Introduction aux Web components (DNG Consulting)

Conclusion

Web Component s’appuie sur des standards HTML

Custom Element

HTML Template

Shadow DOM

HTML Import

Tous les navigateurs ne les implémentent pas, mais

webcomponent.js permet de palier en grande partie à ces

manques

Reste tout de même beaucoup de code à écrire pour

simplement déclarer nos Web Component

Des Frameworks peuvent nous aider à gagner en

efficacité 36

Page 37: Introduction aux Web components (DNG Consulting)

LES FRAMEWORKS

37

Page 38: Introduction aux Web components (DNG Consulting)

Framework existants

Polymer

Projet créé par Google en 2010, à l’origine du projet webcomponent.js

(polyfill)

Bibliothèque de composant Elements, la plus riche

Syntaxe déclarative, databinding, gesture

X-Tags : projet initié par la fondation Mozilla officialisé en

Janvier 2013

Aucune syntaxe déclarative

Propose une bibliothèque de composants (Brick)

Moins riche fonctionnellement que Element de Polymer

Bosonic

Publié en 2014, un seul contributeur, supporte IE 9, Approche

différente de Polymer et X-Tags, utilise un compilateur/traducteur 38

Page 39: Introduction aux Web components (DNG Consulting)

DEMO POLYMER

39