Repository with sources and generator of https://larlet.fr/david/ https://larlet.fr/david/
您最多选择25个主题 主题必须以字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179
  1. title: Un Web orienté composants
  2. slug: web-oriente-composants
  3. date: 2013-10-08
  4. chapo: Les Web Components ont certainement leur carte à jouer dans l’avenir du Web et de ses interactions.
  5. *Article initialement publié pour [le magazine le train de 13h37](http://letrainde13h37.fr/) avec pour titre [Un Web orienté composants](http://letrainde13h37.fr/45/web-oriente-composants/) sous [licence CC BY-NC-SA](https://creativecommons.org/licenses/by-nc-sa/2.0/fr/legalcode) et [rapatrié depuis sur cet espace](/david/blog/2014/rapatriement-articles/).*
  6. Si vous avez eu l’occasion dans votre carrière d’utiliser Flash ou — soyons fous — des [applets Java](https://fr.wikipedia.org/wiki/Applet_Java), vous êtes déjà familier avec la notion de composant. Il s’agit d’un élément de base pouvant être réutilisé, assemblé, combiné, étendu dans le but de faciliter un développement. Dans le cadre des _Web Components_, il s’agit d’éléments `HTML` embarquant leurs propres `CSS` et `JavaScript` afin d’avoir **nativement** un rendu et un comportement uniformes lors de leurs utilisations dans une page ou une application web. Un composant peut aller d’un simple bouton à un _widget_ complet en passant par un élément non-visuel (comme une connexion _AJAX_) mais nous allons détailler tout cela par la suite.
  7. **Attention :** les _Web Components_ sont encore en cours de spécification et les _polyfills_ comme _X-Tag_ ou _Polymer_ dont il est question dans la suite de l’article évoluent très vite. Il est pour l’instant déconseillé d’utiliser ces technologies en production car elles sont relativement instables, on vous aura prévenu(e)s !
  8. ## Des concepts en cours de standardisation…
  9. Poussés par l’équipe Chrome de Google, les _Web Components_ sont [en cours de standardisation](https://dvcs.w3.org/hg/webcomponents/raw-file/tip/explainer/index.html) via le processus classique du W3C, à l’état de brouillon. Le modèle de composant se découpe en 5 parties :
  10. * **Les templates** : permettent de définir des fragments de `HTML` pour une utilisation future sans qu’ils soient interprétés ;
  11. * **Les décorateurs** : pour styler les _templates_ sans que les styles `CSS` s’appliquent aux autres éléments de la page ;
  12. * **Les custom elements** : pour permettre aux développeurs de définir leurs propres éléments avec leurs propres tags `HTML` ;
  13. * **Le Shadow DOM** : qui encapsule un élément complet [à la manière des widgets natifs des navigateurs](http://glazkov.com/2011/01/14/what-the-heck-is-shadow-dom/) ;
  14. * **Les imports** : afin de pouvoir charger des _composants_ depuis une adresse distante.
  15. Note : d’autres innovations sont en cours d’exploration comme les _Pointers Events_, les _Web Animations_ ou les _Model Driven View_ mais ça commence à faire beaucoup pour un seul article !
  16. À ces spécifications s’ajoute le fait de pouvoir [observer un objet](http://weblog.bocoup.com/javascript-object-observe/) `JavaScript` grâce à `Object.observe` (ou _Mutation Observers_ si vous voulez briller en société) et modifier le DOM à la volée.
  17. ## …mais des fonctionnalités déjà utilisables !
  18. Ces spécifications ne sont bien évidement pas encore implémentées dans les navigateurs — même très récents — c’est pourquoi des équipes de développeurs courageux codent en `JavaScript` des compléments appelés _polyfills_ qui miment le comportement que devrait avoir chaque navigateur s’il implémentait les spécifications des _Web Components_. Ces ajouts deviendront inutiles lorsque les différents moteurs de rendus auront travaillé sur ces spécifications.
  19. Il existe 2 projets pour utiliser dès maintenant les _Web Components_ : [X-Tag](http://x-tags.org/) par Mozilla et [Polymer](http://www.polymer-project.org/) par Google. Une compatibilité partielle est prévue entre ces deux projets et nous allons nous concentrer sur Polymer dans la suite de cet article.
  20. ## Une nouvelle façon de penser ses pages
  21. Si vous connaissez [les concepts sous-jacents](http://fr.slideshare.net/stubbornella/styleguide-jsconf) des [CSS Orientées Objets](http://oocss.org/), sachez que les _Web Components_ vont encore plus loin en proposant de véritables composants indépendants, réutilisables et pleinement fonctionnels. Ils ne se limitent pas au style mais intègrent aussi le comportement, autrement dit la logique qui régit le cycle de vie du composant et ses interactions avec l’utilisateur.
  22. Si ces dernières années ont fait la part belle aux _frameworks_ `CSS` comme [Bootstrap](http://twitter.github.io/bootstrap/), [Foundation](http://foundation.zurb.com/) ou [Pure](http://purecss.io/), **ces prochains mois vont voir l’émergence de _toolkits_ proposant des briques de composants aux styles unifiés et aux comportement extensibles.** Certains projets comme [Brick](http://mozilla.github.io/brick/) ou [Quetzal](http://janmiksovsky.github.io/quetzal/) ont d’ailleurs vu le jour dans ce sens. Mais assez de théorie et voyons voir ce à quoi ressemble concrètement un composant web.
  23. ## Un exemple d’application
  24. Nous allons créer un composant permettant d’afficher de manière synthétique les informations relatives à un dépôt Github sur ces propres pages. C’est ce que fait déjà plus ou moins le plugin [GitHub jQuery Repo Widget](https://github.com/JoelSutherland/GitHub-jQuery-Repo-Widget) dont nous allons nous inspirer.
  25. Notre objectif est de pouvoir intégrer facilement le composant dans nos pages de la manière suivante :
  26. <div class="wp_syntax"><table><tr><td class="code"><pre class="html5" style="font-family:monospace;"><span style="color: #009900;">&lt;github-repository repository<span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;scopyleft/web-components&quot;</span>&gt;&lt;<span style="color: #66cc66;">/</span>github-repository&gt;</span></pre></td></tr></table></div>
  27. Cette simple ligne devant afficher le composant relatif au dépôt passé en paramètre avec les styles dédiés et un chargement dynamique des informations en JavaScript. La première étape est de créer notre page `HTML 5`, appelons-la dans un excès d’originalité `index.html` :
  28. <div class="wp_syntax"><table><tr><td class="code"><pre class="html5" style="font-family:monospace;"><span style="color: #00bbdd;">&lt;!DOCTYPE html&gt;</span>
  29. <span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">html</span>&gt;</span>
  30. <span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">head</span>&gt;</span>
  31. <span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">script</span> <span style="color: #000066;">src</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;polymer.min.js&quot;</span>&gt;&lt;<span style="color: #66cc66;">/</span><span style="color: #000000; font-weight: bold;">script</span>&gt;</span>
  32. <span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">link</span> <span style="color: #000066;">rel</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;import&quot;</span> <span style="color: #000066;">href</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;github-repository.html&quot;</span>&gt;</span>
  33. <span style="color: #009900;">&lt;<span style="color: #66cc66;">/</span><span style="color: #000000; font-weight: bold;">head</span>&gt;</span>
  34. <span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">body</span>&gt;</span>
  35. <span style="color: #009900;">&lt;github-repository repository<span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;scopyleft/web-components&quot;</span>&gt;&lt;<span style="color: #66cc66;">/</span>github-repository&gt;</span>
  36. <span style="color: #009900;">&lt;<span style="color: #66cc66;">/</span><span style="color: #000000; font-weight: bold;">body</span>&gt;</span>
  37. <span style="color: #009900;">&lt;<span style="color: #66cc66;">/</span><span style="color: #000000; font-weight: bold;">html</span>&gt;</span></pre></td></tr></table></div>
  38. On commence par charger la bibliothèque `polymer.min.js` (ce fichier s’appelle actuellement `polymer-v0.0.20130912.min.js` si vous téléchargez l’archive directement sur le site) et on importe l’élément `github-repository` depuis une autre page web au nom éponyme (cela n’est pas obligatoire mais c’est une bonne pratique pour avoir des composants réutilisables). On peut maintenant lancer un serveur local, si vous avez Python il suffit de taper cette commande dans le dossier contenant le fichier `index.html` nouvellement créé :
  39. <div class="wp_syntax"><table><tr><td class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #666666;">$ </span>python <span style="color: #660033;">-m</span> SimpleHTTPServer <span style="color: #000000;">8765</span></pre></td></tr></table></div>
  40. Si vous n’avez pas python, vous pouvez configurer un serveur Apache ou n’importe quelle solution permettant de servir des pages web depuis le dossier courant.
  41. En accédant à `http://localhost:8765` vous devriez avoir une page blanche et la console devrait vous indiquer que l’URL `github-repository.html` vous renvoie une 404. Normal, nous ne l’avons pas encore créée ! Créons ce fichier localement en commençant notre composant avec un attribut `repository` puisque l’on souhaite le rendre dynamique :
  42. <div class="wp_syntax"><table><tr><td class="code"><pre class="html5" style="font-family:monospace;"><span style="color: #009900;">&lt;polymer-element <span style="color: #000066;">name</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;github-repository&quot;</span> attributes<span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;repository&quot;</span>&gt;</span></pre></td></tr></table></div>
  43. Il est ensuite composé de 2 parties, la première contenant les styles et le html sous la balise `template` :
  44. <div class="wp_syntax"><table><tr><td class="code"><pre class="html5" style="font-family:monospace;"><span style="color: #009900;">&lt;template&gt;</span>
  45. <span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">style</span>&gt;</span>
  46. @host {
  47. :scope {font-family:helvetica,arial,sans-serif;font-size:13px;line-height:18px;background:#fafafa;border:1px solid #ddd;color:#666;border-radius:3px}
  48. :scope a{color:#4183c4;border:0;text-decoration:none}
  49. :scope.github-box-title{position:relative;border-bottom:1px solid #ddd;border-radius:3px 3px 0 0;background:#fcfcfc;background:-moz-linear-gradient(#fcfcfc,#ebebeb);background:-webkit-linear-gradient(#fcfcfc,#ebebeb);}
  50. :scope.github-box-title h3{font-family:helvetica,arial,sans-serif;font-weight:normal;font-size:16px;color:gray;margin:0;padding:10px 10px 10px 30px;background:url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABIAAAAXCAMAAAAx3e/WAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAyRpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuMC1jMDYxIDY0LjE0MDk0OSwgMjAxMC8xMi8wNy0xMDo1NzowMSAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RSZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENTNS4xIE1hY2ludG9zaCIgeG1wTU06SW5zdGFuY2VJRD0ieG1wLmlpZDpEQjIyNkJERkM0NjYxMUUxOEFDQzk3ODcxRDkzRjhCRSIgeG1wTU06RG9jdW1lbnRJRD0ieG1wLmRpZDpEQjIyNkJFMEM0NjYxMUUxOEFDQzk3ODcxRDkzRjhCRSI+IDx4bXBNTTpEZXJpdmVkRnJvbSBzdFJlZjppbnN0YW5jZUlEPSJ4bXAuaWlkOkRCMjI2QkREQzQ2NjExRTE4QUNDOTc4NzFEOTNGOEJFIiBzdFJlZjpkb2N1bWVudElEPSJ4bXAuZGlkOkRCMjI2QkRFQzQ2NjExRTE4QUNDOTc4NzFEOTNGOEJFIi8+IDwvcmRmOkRlc2NyaXB0aW9uPiA8L3JkZjpSREY+IDwveDp4bXBtZXRhPiA8P3hwYWNrZXQgZW5kPSJyIj8+dka2KgAAAEVQTFRFxMTEyMjI0tLSvb29vr6+zc3Ny8vLxcXFz8/P6enp3t7ex8fH0dHR1NTUw8PDwMDAzs7OvLy8wcHBu7u7v7+/zMzM////budQFwAAABd0Uk5T/////////////////////////////wDmQOZeAAAAcklEQVR42tSQSQ7DMAwD6chOukWs5eX/Ty2coo0T9wOdEzEgdRBuzNmnDofgja52JDyz5TCqUp0O6kfrb4bzSXkRiTviEZZ6JKLMJ5VQ2v8iGbtbfEwXmjFMG0VwdQo10hQNxYqtLMv9O6xvpZ/QeAkwAKjwHiJLaJc3AAAAAElFTkSuQmCC') 7px center no-repeat}
  51. :scope.github-box-title h3.repo{font-weight:bold}
  52. :scope.github-box-title.github-stats{position:absolute;top:8px;right:10px;background:white;border:1px solid #ddd;border-radius:3px;font-size:11px;font-weight:bold;line-height:21px;height:21px}
  53. :scope.github-box-title.github-stats a{display:inline-block;height:21px;color:#666;padding:0 5px 0 18px;background: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAqCAMAAACEJ4viAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAyRpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuMC1jMDYxIDY0LjE0MDk0OSwgMjAxMC8xMi8wNy0xMDo1NzowMSAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RSZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENTNS4xIE1hY2ludG9zaCIgeG1wTU06SW5zdGFuY2VJRD0ieG1wLmlpZDpEQjIyNkJEQkM0NjYxMUUxOEFDQzk3ODcxRDkzRjhCRSIgeG1wTU06RG9jdW1lbnRJRD0ieG1wLmRpZDpEQjIyNkJEQ0M0NjYxMUUxOEFDQzk3ODcxRDkzRjhCRSI+IDx4bXBNTTpEZXJpdmVkRnJvbSBzdFJlZjppbnN0YW5jZUlEPSJ4bXAuaWlkOkRCMjI2QkQ5QzQ2NjExRTE4QUNDOTc4NzFEOTNGOEJFIiBzdFJlZjpkb2N1bWVudElEPSJ4bXAuZGlkOkRCMjI2QkRBQzQ2NjExRTE4QUNDOTc4NzFEOTNGOEJFIi8+IDwvcmRmOkRlc2NyaXB0aW9uPiA8L3JkZjpSREY+IDwveDp4bXBtZXRhPiA8P3hwYWNrZXQgZW5kPSJyIj8+h1kA9gAAAK5QTFRF+fn5sbGx8fHx09PTmpqa2dnZ/f3919fX9PT00NDQ1dXVpKSk+vr6+/v7vb298vLyycnJ8/PztLS0zc3N6enp/v7+q6ur2NjY9/f3srKy/Pz8p6en7u7uoaGhnJyc4eHhtbW1pqam6Ojo9fX17e3toqKirKys1NTUzs7Ox8fHwcHBwMDA5eXlnZ2dpaWl0dHR9vb25ubm4uLi3d3dqqqqwsLCv7+/oKCgmZmZ////8yEsbwAAAMBJREFUeNrE0tcOgjAUBuDSliUoMhTEvfdef9//xUQjgaLX0Ium/ZLT/+SkRPxZpGykvuf5VMJogy5jY9yjDHcWFhqlcRuHc4o6B1QK0BDg+hcZgNDh3NWTwzItH/bRrhvT+g3zSxZkNGCZpoWGIbU0a3Y6zV5VA6keyeDxiw62P0gUqEW0FbDim4nVikFJbU2zZXybUEaxhCqOQqyh5/G0wpWICUwthyqwD4InOMuXJ7/gs7WkoPdVg1vykF8CDACEFanKO3aSYwAAAABJRU5ErkJggg==') no-repeat}
  54. :scope.github-box-title.github-stats.watchers{border-right:1px solid #ddd}
  55. :scope.github-box-title.github-stats.forks{background-position:-4px -21px;padding-left:15px}
  56. :scope.github-box-content{padding:10px;font-weight:300}
  57. :scope.github-box-content p{margin:0}
  58. :scope.github-box-content.link{font-weight:bold}
  59. :scope.github-box-download{position:relative;border-top:1px solid #ddd;background:white;border-radius:0 0 3px 3px;padding:10px;height:24px}
  60. :scope.github-box-download.updated{margin:0;font-size:11px;color:#666;line-height:24px;font-weight:300}
  61. :scope.github-box-download.updated strong{font-weight:bold;color:#000}
  62. :scope.github-box-download.download{position:absolute;display:block;top:10px;right:10px;height:24px;line-height:24px;font-size:12px;color:#666;font-weight:bold;text-shadow:0 1px 0 rgba(255,255,255,0.9);padding:0 10px;border:1px solid #ddd;border-bottom-color:#bbb;border-radius:3px;background:#f5f5f5;background:-moz-linear-gradient(#f5f5f5,#e5e5e5);background:-webkit-linear-gradient(#f5f5f5,#e5e5e5);}
  63. :scope.github-box-download.download:hover{color:#527894;border-color:#cfe3ed;border-bottom-color:#9fc7db;background:#f1f7fa;background:-moz-linear-gradient(#f1f7fa,#dbeaf1);background:-webkit-linear-gradient(#f1f7fa,#dbeaf1);}
  64. }
  65. <span style="color: #009900;">&lt;<span style="color: #66cc66;">/</span><span style="color: #000000; font-weight: bold;">style</span>&gt;</span>
  66. <span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">div</span> <span style="color: #000066;">class</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;repo&quot;</span> <span style="color: #000066;">style</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;width: {{ width }}&quot;</span>&gt;</span>
  67. <span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">div</span> <span style="color: #000066;">class</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;github-box-title&quot;</span>&gt;</span>
  68. <span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">h3</span>&gt;</span>
  69. <span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">a</span> <span style="color: #000066;">class</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;owner&quot;</span> <span style="color: #000066;">href</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;{{ ownerUrl }}&quot;</span>&gt;</span>{{ login }}<span style="color: #009900;">&lt;<span style="color: #66cc66;">/</span><span style="color: #000000; font-weight: bold;">a</span>&gt;</span>
  70. /
  71. <span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">a</span> <span style="color: #000066;">class</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;repo&quot;</span> <span style="color: #000066;">href</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;{{ repoUrl }}&quot;</span>&gt;</span>{{ name }}<span style="color: #009900;">&lt;<span style="color: #66cc66;">/</span><span style="color: #000000; font-weight: bold;">a</span>&gt;</span>
  72. <span style="color: #009900;">&lt;<span style="color: #66cc66;">/</span><span style="color: #000000; font-weight: bold;">h3</span>&gt;</span>
  73. <span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">div</span> <span style="color: #000066;">class</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;github-stats&quot;</span>&gt;</span>
  74. <span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">a</span> <span style="color: #000066;">class</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;watchers&quot;</span> <span style="color: #000066;">href</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;{{ watchersUrl }}&quot;</span>&gt;</span>{{ watchers }}<span style="color: #009900;">&lt;<span style="color: #66cc66;">/</span><span style="color: #000000; font-weight: bold;">a</span>&gt;</span>
  75. <span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">a</span> <span style="color: #000066;">class</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;forks&quot;</span> <span style="color: #000066;">href</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;{{ forksUrl }}&quot;</span>&gt;</span>{{ forks }}<span style="color: #009900;">&lt;<span style="color: #66cc66;">/</span><span style="color: #000000; font-weight: bold;">a</span>&gt;</span>
  76. <span style="color: #009900;">&lt;<span style="color: #66cc66;">/</span><span style="color: #000000; font-weight: bold;">div</span>&gt;</span>
  77. <span style="color: #009900;">&lt;<span style="color: #66cc66;">/</span><span style="color: #000000; font-weight: bold;">div</span>&gt;</span>
  78. <span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">div</span> <span style="color: #000066;">class</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;github-box-content&quot;</span>&gt;</span>
  79. <span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">p</span> <span style="color: #000066;">class</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;description&quot;</span>&gt;</span>{{ description }} <span style="color: #ddbb00;">&amp;mdash;</span> <span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">a</span> <span style="color: #000066;">href</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;{{ readmeUrl }}&quot;</span>&gt;</span>Read More<span style="color: #009900;">&lt;<span style="color: #66cc66;">/</span><span style="color: #000000; font-weight: bold;">a</span>&gt;&lt;<span style="color: #66cc66;">/</span><span style="color: #000000; font-weight: bold;">p</span>&gt;</span>
  80. <span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">p</span> <span style="color: #000066;">class</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;link&quot;</span>&gt;&lt;<span style="color: #000000; font-weight: bold;">a</span> <span style="color: #000066;">href</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;{{ homepage }}&quot;</span>&gt;</span>{{ homepage }}<span style="color: #009900;">&lt;<span style="color: #66cc66;">/</span><span style="color: #000000; font-weight: bold;">a</span>&gt;&lt;<span style="color: #66cc66;">/</span><span style="color: #000000; font-weight: bold;">p</span>&gt;</span>
  81. <span style="color: #009900;">&lt;<span style="color: #66cc66;">/</span><span style="color: #000000; font-weight: bold;">div</span>&gt;</span>
  82. <span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">div</span> <span style="color: #000066;">class</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;github-box-download&quot;</span>&gt;</span>
  83. <span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">p</span> <span style="color: #000066;">class</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;updated&quot;</span>&gt;</span>Latest commit to the <span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">strong</span>&gt;</span>master<span style="color: #009900;">&lt;<span style="color: #66cc66;">/</span><span style="color: #000000; font-weight: bold;">strong</span>&gt;</span> branch on {{ pushedAt }}<span style="color: #009900;">&lt;<span style="color: #66cc66;">/</span><span style="color: #000000; font-weight: bold;">p</span>&gt;</span>
  84. <span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">a</span> <span style="color: #000066;">class</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;download&quot;</span> <span style="color: #000066;">href</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;{{ downloadUrl }}&quot;</span>&gt;</span>Download as zip<span style="color: #009900;">&lt;<span style="color: #66cc66;">/</span><span style="color: #000000; font-weight: bold;">a</span>&gt;</span>
  85. <span style="color: #009900;">&lt;<span style="color: #66cc66;">/</span><span style="color: #000000; font-weight: bold;">div</span>&gt;</span>
  86. <span style="color: #009900;">&lt;<span style="color: #66cc66;">/</span><span style="color: #000000; font-weight: bold;">div</span>&gt;</span>
  87. <span style="color: #009900;">&lt;<span style="color: #66cc66;">/</span>template&gt;</span></pre></td></tr></table></div>
  88. Cela fait beaucoup d’information mais il ne faut pas s’affoler, les `CSS` sont assez verbeuses car elles intègrent les images mais sont juste là pour définir les styles propres à Github. Il s’agit de déclaration classiques qui peuvent être _inline_ comme ici ou plus aérées. La seule particularité est relative à la combinaison du `@host` et du `:scope` qui permettent de restreindre les styles au composant, pratique lorsque l’on souhaite intégrer des composants de plusieurs provenances ! Il est possible de remplacer le `:scope` par un `id` sur la `div` principale mais cela est moins élégant (notez que [la syntaxe pourrait changer prochainement](https://www.w3.org/Bugs/Public/show_bug.cgi?id=22390)).
  89. La partie `HTML` est plus intéressante avec l’utilisation de variables écrites entre `{{ }}`, syntaxe avec laquelle vous êtes peut-être déjà familier. Celles-ci seront complétées directement avec le `JavaScript` qui est inséré à la suite du fichier dans une balise `<script>` :
  90. <div class="wp_syntax"><table><tr><td class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #339933;">&lt;</span>script<span style="color: #339933;">&gt;</span>
  91. Polymer<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'github-repository'</span><span style="color: #339933;">,</span> <span style="color: #009900;">&#123;</span>
  92. width<span style="color: #339933;">:</span> <span style="color: #3366CC;">'500px'</span><span style="color: #339933;">,</span>
  93. created<span style="color: #339933;">:</span> <span style="color: #000066; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
  94. <span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">vendorName</span> <span style="color: #339933;">=</span> <span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">repository</span>.<span style="color: #660066;">split</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'/'</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#91;</span><span style="color: #CC0000;">0</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
  95. <span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">repoName</span> <span style="color: #339933;">=</span> <span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">repository</span>.<span style="color: #660066;">split</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'/'</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#91;</span><span style="color: #CC0000;">1</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
  96. <span style="color: #009900;">&#125;</span><span style="color: #339933;">,</span>
  97. enteredView<span style="color: #339933;">:</span> <span style="color: #000066; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
  98. <span style="color: #000066; font-weight: bold;">var</span> url <span style="color: #339933;">=</span> <span style="color: #3366CC;">'https://api.github.com/repos/'</span> <span style="color: #339933;">+</span> <span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">repository</span><span style="color: #339933;">,</span>
  99. httpRequest <span style="color: #339933;">=</span> <span style="color: #000066; font-weight: bold;">new</span> XMLHttpRequest<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span>
  100. self <span style="color: #339933;">=</span> <span style="color: #000066; font-weight: bold;">this</span><span style="color: #339933;">;</span>
  101. httpRequest.<span style="color: #660066;">open</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'GET'</span><span style="color: #339933;">,</span> url<span style="color: #339933;">,</span> <span style="color: #003366; font-weight: bold;">true</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  102. httpRequest.<span style="color: #660066;">send</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  103. httpRequest.<span style="color: #660066;">onreadystatechange</span> <span style="color: #339933;">=</span> <span style="color: #000066; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
  104. <span style="color: #000066; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">status</span> <span style="color: #339933;">!==</span> <span style="color: #CC0000;">200</span> <span style="color: #339933;">||</span> <span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">readyState</span> <span style="color: #339933;">!==</span> <span style="color: #CC0000;">4</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
  105. <span style="color: #000066; font-weight: bold;">return</span><span style="color: #339933;">;</span>
  106. <span style="color: #009900;">&#125;</span>
  107. <span style="color: #000066; font-weight: bold;">var</span> repo <span style="color: #339933;">=</span> JSON.<span style="color: #660066;">parse</span><span style="color: #009900;">&#40;</span><span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">responseText</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  108. self.<span style="color: #660066;">login</span> <span style="color: #339933;">=</span> repo.<span style="color: #660066;">owner</span>.<span style="color: #660066;">login</span><span style="color: #339933;">;</span>
  109. self.<span style="color: #660066;">ownerUrl</span> <span style="color: #339933;">=</span> repo.<span style="color: #660066;">owner</span>.<span style="color: #660066;">html_url</span><span style="color: #339933;">;</span>
  110. self.<span style="color: #660066;">name</span> <span style="color: #339933;">=</span> repo.<span style="color: #660066;">name</span><span style="color: #339933;">;</span>
  111. self.<span style="color: #660066;">repoUrl</span> <span style="color: #339933;">=</span> repo.<span style="color: #660066;">html_url</span>
  112. self.<span style="color: #660066;">watchers</span> <span style="color: #339933;">=</span> repo.<span style="color: #660066;">watchers</span><span style="color: #339933;">;</span>
  113. self.<span style="color: #660066;">watchersUrl</span> <span style="color: #339933;">=</span> self.<span style="color: #660066;">repoUrl</span> <span style="color: #339933;">+</span> <span style="color: #3366CC;">&quot;/watchers&quot;</span><span style="color: #339933;">;</span>
  114. self.<span style="color: #660066;">forks</span> <span style="color: #339933;">=</span> repo.<span style="color: #660066;">forks</span><span style="color: #339933;">;</span>
  115. self.<span style="color: #660066;">forksUrl</span> <span style="color: #339933;">=</span> self.<span style="color: #660066;">repoUrl</span> <span style="color: #339933;">+</span> <span style="color: #3366CC;">&quot;/forks&quot;</span><span style="color: #339933;">;</span>
  116. self.<span style="color: #660066;">description</span> <span style="color: #339933;">=</span> repo.<span style="color: #660066;">description</span><span style="color: #339933;">;</span>
  117. self.<span style="color: #660066;">homepage</span> <span style="color: #339933;">=</span> repo.<span style="color: #660066;">homepage</span><span style="color: #339933;">;</span>
  118. <span style="color: #000066; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>repo.<span style="color: #660066;">has_wiki</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
  119. self.<span style="color: #660066;">readmeUrl</span> <span style="color: #339933;">=</span> self.<span style="color: #660066;">repoUrl</span> <span style="color: #339933;">+</span> <span style="color: #3366CC;">&quot;#readme&quot;</span><span style="color: #339933;">;</span>
  120. <span style="color: #009900;">&#125;</span><span style="color: #339933;">;</span>
  121. <span style="color: #000066; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>repo.<span style="color: #660066;">pushed_at</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
  122. date <span style="color: #339933;">=</span> <span style="color: #000066; font-weight: bold;">new</span> <span style="">Date</span><span style="color: #009900;">&#40;</span>repo.<span style="color: #660066;">pushed_at</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  123. <span style="color: #000066; font-weight: bold;">function</span> pad<span style="color: #009900;">&#40;</span>n<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span> <span style="color: #000066; font-weight: bold;">return</span> n<span style="color: #339933;">&lt;</span><span style="color: #CC0000;">10</span> <span style="color: #339933;">?</span> <span style="color: #3366CC;">'0'</span><span style="color: #339933;">+</span>n <span style="color: #339933;">:</span> n <span style="color: #009900;">&#125;</span><span style="color: #339933;">;</span>
  124. self.<span style="color: #660066;">pushedAt</span> <span style="color: #339933;">=</span> date.<span style="color: #660066;">getFullYear</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">+</span> <span style="color: #3366CC;">'-'</span> <span style="color: #339933;">+</span> pad<span style="color: #009900;">&#40;</span>date.<span style="color: #660066;">getMonth</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">+</span> <span style="color: #CC0000;">1</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">+</span> <span style="color: #3366CC;">'-'</span> <span style="color: #339933;">+</span> pad<span style="color: #009900;">&#40;</span>date.<span style="color: #660066;">getDate</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  125. <span style="color: #009900;">&#125;</span>
  126. self.<span style="color: #660066;">downloadUrl</span> <span style="color: #339933;">=</span> self.<span style="color: #660066;">repoUrl</span> <span style="color: #339933;">+</span> <span style="color: #3366CC;">&quot;/zipball/master&quot;</span><span style="color: #339933;">;</span>
  127. <span style="color: #009900;">&#125;</span><span style="color: #339933;">;</span>
  128. <span style="color: #009900;">&#125;</span>
  129. <span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  130. <span style="color: #339933;">&lt;/</span>script<span style="color: #339933;">&gt;</span></pre></td></tr></table></div>
  131. On commence par définir la largeur par défaut du composant, avec une valeur par défaut de 500 pixels (le lecteur bidouilleur pourra tenter de rendre cette valeur dynamique en la passant en attribut). La fonction `created` est appelée à l’instanciation et permet de définir le nom d’utilisateur et le dépôt concernés.
  132. La fonction `enteredView` est la plus intéressante car elle permet d’effectuer la requête `AJAX` récupérant les informations du dépôt et de remplacer _automagiquement_ celles-ci dans le `template` précédemment défini.
  133. On n’oublie bien évidemment pas de refermer la balise `</polymer-element>` à la fin de notre fichier. En rafraichissant la page, vous devriez apercevoir votre composant apparaître avec les informations relatives au dépôt que vous avez renseigné en attribut du composant (ici `scopyleft/web-components`).
  134. ## Et la suite ?
  135. Deux vidéos en anglais d’interventions réalisées dans le cadre de Google I/O font référence à ce jour et permettent de voir les exemples en pratique si vous n’êtes pas encore prêt(e) à mettre les mains dans le code :
  136. * [Web Components: A Tectonic Shift for Web Development](https://www.youtube.com/watch?v=fqULJBBEVQE)
  137. * [Web Components in Action](https://www.youtube.com/watch?v=0g0oOOT86NY)
  138. Miško Hevery, l’un des co-créateurs d’[AngularJS](http://angularjs.org/), s’est déjà prononcé en faveur d’une intégration partielle et d’une compatibilité avec les _Web Components_ développé avec Polymer pour la version 2.0 du framework [sur la liste de diffusion du développement de Polymer](https://groups.google.com/forum/#!msg/polymer-dev/4RSYaKmbtEk/uYnY3900wpIJ).
  139. En ce qui concerne [EmberJS](http://emberjs.com/), c’est plus compliqué en raison des problématiques de performances que cela entraîne mais [l’objectif à long terme](https://gist.github.com/wycats/9144666b0c606d1838be) est d’être compatible également.
  140. Autant d’encouragements pour développer (et [partager](http://customelements.io/)) dès à présent votre _toolkit_ de composants web afin de passer [d’un développement atomique](http://bradfrostweb.com/blog/post/atomic-web-design/) à un développement moléculaire ! Les _Web Components_ ont certainement [leur carte à jouer](http://insideintercom.io/why-cards-are-the-future-of-the-web/) dans l’avenir du Web et de ses interactions.