<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	xmlns:series="http://organizeseries.com/"
	>

<channel>
	<title>Web Components &#8211; HTML5Experts.jp</title>
	<atom:link href="/tag/web-components/feed/" rel="self" type="application/rss+xml" />
	<link>https://html5experts.jp</link>
	<description>日本に、もっとエキスパートを。</description>
	<lastBuildDate>Sat, 07 Jul 2018 03:14:05 +0000</lastBuildDate>
	<language>ja</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>https://wordpress.org/?v=4.7.19</generator>
	<item>
		<title>Web Componentsについて気になること、泉水さんに全部聞いてきました！</title>
		<link>/shumpei-shiraishi/24239/</link>
		<pubDate>Thu, 21 Sep 2017 01:05:10 +0000</pubDate>
		<dc:creator><![CDATA[白石 俊平]]></dc:creator>
				<category><![CDATA[最新動向]]></category>
		<category><![CDATA[Custom Elements]]></category>
		<category><![CDATA[Shadow DOM]]></category>
		<category><![CDATA[Web Components]]></category>

		<guid isPermaLink="false">/?p=24239</guid>
		<description><![CDATA[連載： HTML5 Conference 2017特集 (8)こんにちは、編集長の白石です。 この記事は、9月24日に開催されるHTML5 Conference 2017に登壇するエキスパートに、予定しているセッションの...]]></description>
				<content:encoded><![CDATA[<div class="seriesmeta">連載： <a href="https://html5experts.jp/series/html5-conf2017/" class="series-457" title="HTML5 Conference 2017特集" data-wpel-link="internal">HTML5 Conference 2017特集</a> (8)</div><p>こんにちは、編集長の白石です。</p>

<p>この記事は、9月24日に開催される<a href="http://events.html5j.org/conference/2017/9/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">HTML5 Conference 2017</a>に登壇するエキスパートに、予定しているセッションのトピックを中心に、様々な技術的なお話を伺おうというものです。セッションの内容をより深く理解する手助けになるだけでなく、本記事単体でも面白く読んでいただけることを目指しています。</p>

<p>今回お話を伺ったのは、株式会社サイバーエージェントにお勤めの泉水翔吾さんです。</p>

<p><img src="/wp-content/uploads/2017/09/ce4ef7d68f1accac27a33bbf3fb35849.jpg" alt="" width="640" height="417" class="alignnone size-full wp-image-24289" srcset="/wp-content/uploads/2017/09/ce4ef7d68f1accac27a33bbf3fb35849.jpg 640w, /wp-content/uploads/2017/09/ce4ef7d68f1accac27a33bbf3fb35849-300x195.jpg 300w, /wp-content/uploads/2017/09/ce4ef7d68f1accac27a33bbf3fb35849-207x135.jpg 207w" sizes="(max-width: 640px) 100vw, 640px" /><br><span style="font-size: 80%;">▲<strong>株式会社サイバーエージェント 泉水翔吾さん</strong></span></p>

<p>泉水さんのセッションは「<a href="http://events.html5j.org/conference/2017/9/session/#a5" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">The State of Web Components</a>」（ルームA 16:20-17:00）です。
（現在<a href="https://html5j.connpass.com/event/64992/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">HTML5 Conference</a>は定員オーバーの状態ですが、無料イベントということもあってキャンセルも多めに出るらしいので、あきらめずにキャンセル待ちすることをお勧めします！）</p>

<h2>Web Componentsについてまずは復習</h2>

<p><b class="speaker siraisi">白石:</b> まずは、Web Componentsについて詳しくご存じない方のために、「Web Componentsとは何か」を簡単にお話していただけますでしょうか？</p>

<p><b class="speaker siraisi">泉水:</b> Web Componentsは、一言で言えば<strong>HTML/CSS/JavaScriptといったWeb技術上で、再利用できる部品作りを促進する仕組み</strong>です。</p>

<p>ReactやAngularなど、昨今のフレームワークを使えば、WebのUIをコンポーネントとして扱うのはすでに可能です。しかし、例えばCSSが単一のグローバルスコープしか持たなかったり、インポートする仕組みが弱かったりするという問題は、ブラウザがネイティブに対応することが望まれる問題なのです。</p>

<p><b class="speaker siraisi">白石:</b> 具体的な技術として見た場合、Web Componentsとはどのような技術なのでしょうか？</p>

<p><b class="speaker siraisi">泉水:</b> <strong>大きく分けて4つの仕様からなっています</strong>。</p>

<p>1つ目は<strong>Shadow DOM</strong>（<a href="https://www.w3.org/TR/shadow-dom/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">仕様</a>）。個人的には一番のポイントとなる技術だと思っています。</p>

<p>コンポーネントはそれぞれ、メインのDOMツリーから分離された、独自のDOMツリーを持つことができるようになり、それをShadow DOMといいます。Shadow DOMはそれぞれ異なるスコープを持つため、CSSやJavaScriptの名前空間が他と干渉しません。</p>

<p>例えば、一度作ったUI部品を、一年後にまた別の箇所で使おうと思った時、CSSのクラス名がかぶってしまってうまく扱えない…などの問題はありがちです。そういう問題を根本的に解決する手段として、Shadow DOMはとても有望な技術です。</p>

<p><img src="/wp-content/uploads/2017/09/71802129d7faf8b2dddc59c46e669afb.jpg" alt="" width="640" height="419" class="alignnone size-full wp-image-24292" srcset="/wp-content/uploads/2017/09/71802129d7faf8b2dddc59c46e669afb.jpg 640w, /wp-content/uploads/2017/09/71802129d7faf8b2dddc59c46e669afb-300x196.jpg 300w, /wp-content/uploads/2017/09/71802129d7faf8b2dddc59c46e669afb-207x136.jpg 207w" sizes="(max-width: 640px) 100vw, 640px" /></p>

<p>2つ目は<strong>Custom Elements</strong>です（<a href="https://www.w3.org/TR/custom-elements/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">仕様</a>）。</p>

<p>これは一言で言うと<strong>「独自の要素を作れる」技術</strong>です。 <code>customElements.define()</code>というAPIを用いて自由に要素を作成でき、作った要素は通常のHTML要素と同じくマークアップが可能です。Web Componentsによる「部品の再定義」とは、この「独自の要素を作って、使える」というCustom Elementsの機能を指すことが多いと思います。</p>

<p>3つ目は<strong>template要素</strong>です（<a href="https://www.w3.org/TR/html5/scripting-1.html#the-template-element" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">仕様</a>）。</p>

<p><strong>テンプレートとして使いたいHTMLを定義するための要素</strong>で、すでにほとんどのブラウザが対応しています。昔は、そういうテンプレートは不可視の<code>div</code>要素だとか、独自の<code>type</code>を指定した<code>script</code>要素の中に書くのが通例でした。</p>

<p>標準の要素を用いてテンプレートを扱えるようになったことで、セマンティクス上わかりやすくなったり、テンプレートをDOMとして扱えるのでセキュリティ上の懸念がある<code>innerHTML</code>を利用する必要がなかったり、テンプレート内に<code>img</code>要素があったときに画像のリクエストが行われてしまう…といった問題を避けられるようになりました。</p>

<p>最後は<strong>HTML Imports</strong>と呼ばれている仕様でした（<a href="https://w3c.github.io/webcomponents/spec/imports/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">仕様</a>）。この仕様はもともと、<code>link</code>要素を用いて他のHTMLファイルを読み込むことができるというものです。</p>

<p>ただ、この仕様には反対するブラウザベンダーも多く、実装は進みませんでした。代わりにES Modules（※）の実装が進んできたので、まずはそれを使ってコンポーネントを宣言するJavaScriptを読み込む…というのが、当面はスタンダードな手段になりそうです。</p>

<p><small>
※ES Modules…<a href="https://tc39.github.io/ecma262/#sec-modules" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">ECMAScriptで定められた</a>、モジュールを扱うための標準仕様。<code>import {XXX} as 'module';</code>のような形式で、他のモジュールを読み込むことができる。
</small></p>

<h2>Web Componentsが「ようやく使える」わけ</h2>

<p><b class="speaker siraisi">白石:</b> 泉水さんが<a href="http://events.html5j.org/conference/2017/9/session/#a5" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">HTML5 Conferenceのセッション説明</a>に書かれていたことによると、<strong>Web Componentsは「ようやくまともに使えるようになりそう」</strong>とのことですね。これまでなぜまともに使えなかったのか、そしてどのように状況が変わってきたのでしょうか？</p>

<p><b class="speaker siraisi">泉水:</b> <strong>ブラウザの対応が進まなかった</strong>というのが、これまでまともに使えなかったという理由です。</p>

<p>Web Componentsはもともと、2011年にGoogleが提案したものでしたが、ブラウザの反対にあったり実装されなかったり…という部分がとても多かった。
Shadow DOMやCustom Elementsの当初の仕様は「v0」（バージョン0）と呼ばれていて、ほぼ「なかったこと」になっています。</p>

<p>しかし、仕切り直された「v1」でようやくブラウザベンダーの合意形成がなされて、実装も進んできた。特にSafariの実装が進んできたのが大きいですね。やはり、iOSの存在感はとても大きいので、Safariで動かないとなると、「使えない」「使いにくい」と見なされるのが普通ですから。</p>

<p><img src="/wp-content/uploads/2017/09/dd6aaa54d1e7188928500b4031b935a9.jpg" alt="" width="640" height="427" class="alignnone size-full wp-image-24293" srcset="/wp-content/uploads/2017/09/dd6aaa54d1e7188928500b4031b935a9.jpg 640w, /wp-content/uploads/2017/09/dd6aaa54d1e7188928500b4031b935a9-300x200.jpg 300w, /wp-content/uploads/2017/09/dd6aaa54d1e7188928500b4031b935a9-207x138.jpg 207w" sizes="(max-width: 640px) 100vw, 640px" /></p>

<p>先程申し上げた仕様で言うと、<a href="http://caniuse.com/#feat=shadowdomv1" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">Shadow DOMはChromeとSafariでほぼ使える</a>。
<a href="http://caniuse.com/#feat=custom-elementsv1" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">Custom Elementsも同様に、ChromeとSafariが対応しています</a>。
<a href="http://caniuse.com/#feat=template" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">template要素はIEを除くほぼすべてのブラウザで使えます</a>し、<a href="http://caniuse.com/#feat=es6-module" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">ES ModulesもChrome、Safariが最新版で対応済み</a>です。</p>

<p><b class="speaker siraisi">白石:</b> こうして見ると、むしろモバイルブラウザのほうがWeb Componentsを使いやすそうですね。最新版のブラウザであれば、ほぼ100%対応している。ようやく、時代がWeb Componentsに追いついてきたという感じですね。</p>

<h2>Web Componentsの「作りかた」</h2>

<p><b class="speaker siraisi">白石:</b> では、Web Componentsに準拠したコンポーネントはどのようにして作るのでしょうか？フレームワークやライブラリを使ったほうがいいですか？</p>

<p><b class="speaker siraisi">泉水:</b> 現時点だと、全てのブラウザがWeb Componentsに対応しているわけではないので、<strong>Polyfillの利用は考えたほうがいい</strong>かもしれませんね。
<a href="https://github.com/webcomponents/webcomponentsjs" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">webcomponents.js</a>というライブラリがあるので、それを読み込んでおけば、あらゆるブラウザでWeb Componentsのコードが動作するようになります。</p>

<p>その上でまずは、<strong>素のJavaScriptで全然作っていける</strong>と思います。<a href="https://github.com/1000ch/webcomponents-sandbox/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">私の作ってみたサンプルがGitHubに上がっているので</a>、そちらを例に取って説明しますね。</p>

<p>まずコンポーネントの作り方ですが、既存のHTML要素を継承したクラスを作ります。</p>

<p></p><pre class="crayon-plain-tag">// fancy-button.js
// ↓のコードを記事用に改変
// https://github.com/1000ch/webcomponents-sandbox/blob/master/fancy-button.js
export default class FancyButton extends HTMLElement {
  static get template() {
    return `
      &lt;style&gt;
        button {
          display: inline-block;
          /* 中略 */
        }
      &lt;/style&gt;
      &lt;button&gt;
        &lt;slot&gt;&lt;/slot&gt;
      &lt;/button&gt;
    `;
  }

  constructor() {
    super();
  }

  connectedCallback() {
    this.attachShadow({
      mode: 'open'
    }).innerHTML = FancyButton.template;
  }
};</pre><p></p>

<p>コンポーネントを使う側は、そのコンポーネントを<code>import</code>で読みこんで、<code>customElements.define()</code>を使ってカスタム要素を生成します。後は普通のHTML要素と同様に使っていけばいい。この例では、<code>&lt;fancy-button&gt;</code>というタグが使えるようになりました。</p>

<p></p><pre class="crayon-plain-tag">// app.js
// ↓のコードを記事用に改変
// https://github.com/1000ch/webcomponents-sandbox/blob/master/app.js
import FancyButton from './fancy-button.js';

customElements.define('fancy-button', FancyButton);</pre><p></p>

<p><b class="speaker siraisi">白石:</b> この例でいくと、<code>style</code>やその他の要素を文字列として定義しておくんですね。</p>

<p><b class="speaker siraisi">泉水:</b> そうですね。将来的にもこうした方法がスタンダードになるかはわかりませんが、現時点では<a href="https://github.com/Polymer/polymer/tree/3.0-preview" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">Polymer 3.0</a>なども同様の方法を取っています。</p>

<p><img src="/wp-content/uploads/2017/09/0a2e89d5a587668cfed4cd5da7d36356.jpg" alt="" width="640" height="420" class="alignnone size-full wp-image-24294" srcset="/wp-content/uploads/2017/09/0a2e89d5a587668cfed4cd5da7d36356.jpg 640w, /wp-content/uploads/2017/09/0a2e89d5a587668cfed4cd5da7d36356-300x197.jpg 300w, /wp-content/uploads/2017/09/0a2e89d5a587668cfed4cd5da7d36356-207x136.jpg 207w" sizes="(max-width: 640px) 100vw, 640px" /></p>

<h2>Web Componentsに関連するライブラリやサービス</h2>

<p><b class="speaker siraisi">白石:</b> <a href="https://www.polymer-project.org/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">Polymer</a>とはなんですか？</p>

<p><b class="speaker siraisi">泉水:</b> Web Componentsの開発を促進するライブラリです。データバインディングなど、コンポーネントを作るのに便利な機能が数多く含まれています。現在は<a href="https://www.polymer-project.org/blog/2017-08-22-npm-modules.html" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">3.0が開発中</a>で、コンポーネントのロード手段がHTML ImportsからES Modulesに変更されたり、APIが大幅に変わったりする予定です。</p>

<p><b class="speaker siraisi">白石:</b> その他、Web Componentsに関連するライブラリとか、サービスってありますか？</p>

<p><b class="speaker siraisi">泉水:</b> <a href="https://www.webcomponents.org/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">webcomponents.org</a>はWebComponentsのポータルサイトで、Web Componentsに関する情報や、公開されているコンポーネントが載っています。Polymerプロジェクトが作ったコンポーネントも多数公開されていて、<a href="https://www.webcomponents.org/search/iron" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">&#8216;iron&#8217;という接頭辞が付いたものはコアコンポーネント</a>、<a href="https://www.webcomponents.org/collection/PolymerElements/paper-elements" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">&#8216;paper&#8217;という接頭辞が付いたものはマテリアルデザインのコンポーネント</a>です。</p>

<p><b class="speaker siraisi">白石:</b> Polymer以外にも、Web Componentsのライブラリってあるんでしょうか？</p>

<p><b class="speaker siraisi">泉水:</b> <a href="https://www.webcomponents.org/introduction#libraries-for-building-web-components" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">webcomponents.orgに一覧があります</a>。例えば、<a href="https://github.com/skatejs/skatejs" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">SkateJS</a>は軽量なライブラリで、Reactライクな仮想DOMを持ち、stateやpropsの管理も行ってくれるというものです。</p>

<h2>YouTubeはWeb Componentsを使っている！</h2>

<p><b class="speaker siraisi">白石:</b> Web Componentsがようやく使える段階に来ているということで、何か事例とかあったりするんでしょうか？</p>

<p><b class="speaker siraisi">泉水:</b> 事例で言うと、<a href="https://react-etc.net/entry/youtube-is-being-rebuilt-on-web-components-and-polymer" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">YouTubeがWeb Componentsを使っている</a>というのは有名ですね。去年発表されて話題になりました。最近デザインもリニューアルされましたが、Polymerを使っているようです。</p>

<p><b class="speaker siraisi">白石:</b> YouTubeが！凄まじい利用者数もいるだろうに、そんなドラスティックな改変を行っているだなんて…。</p>

<p><b class="speaker siraisi">泉水:</b> YouTubeのチームは、すごく攻めるらしいんです(笑) 。ただYouTubeチームは、素のWeb Componentsを使っているわけではありません。</p>

<p>YouTubeのHTMLソースを見てみると、確かにたくさんのカスタム要素を使っているのですが、Shadow DOMは使っていないんです。</p>

<p><img src="/wp-content/uploads/2017/09/79aef22c885b4b8647c52e0222bd8cd7.jpg" alt="" width="640" height="419" class="alignnone size-full wp-image-24295" srcset="/wp-content/uploads/2017/09/79aef22c885b4b8647c52e0222bd8cd7.jpg 640w, /wp-content/uploads/2017/09/79aef22c885b4b8647c52e0222bd8cd7-300x196.jpg 300w, /wp-content/uploads/2017/09/79aef22c885b4b8647c52e0222bd8cd7-207x136.jpg 207w" sizes="(max-width: 640px) 100vw, 640px" /></p>

<p><b class="speaker siraisi">白石:</b> 本当だ、<code>yt-</code>って接頭辞の付いたタグをたくさん使ってるけど、それらの中身は通常のDOMですね。</p>

<p><img src="/wp-content/uploads/2017/09/bd7723deb3f6bdc87b34624d28f979a5.png" alt="" width="302" height="309" class="aligncenter size-full wp-image-24243" srcset="/wp-content/uploads/2017/09/bd7723deb3f6bdc87b34624d28f979a5.png 302w, /wp-content/uploads/2017/09/bd7723deb3f6bdc87b34624d28f979a5-293x300.png 293w, /wp-content/uploads/2017/09/bd7723deb3f6bdc87b34624d28f979a5-202x207.png 202w" sizes="(max-width: 302px) 100vw, 302px" /></p>

<p><b class="speaker siraisi">泉水:</b> 聞くところによると、<a href="https://github.com/webcomponents/shadydom" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">Shady DOM</a>や<a href="https://github.com/webcomponents/shadycss" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">Shady CSS</a>というWeb ComponentsのPolyfillを使っているそうです。Shady DOMやShady CSSは、Web Componentsの動作を完全にエミュレーションするわけではないのですが、そのかわりに動作が軽量です。</p>

<p><b class="speaker siraisi">白石:</b> なるほど、それでWeb Componentsと互換性のあるコードを書いているというわけですね、きっと。</p>

<p><img src="/wp-content/uploads/2017/09/c697a7cf33dfa2b08c65806c744b978a.jpg" alt="" width="640" height="427" class="alignnone size-full wp-image-24296" srcset="/wp-content/uploads/2017/09/c697a7cf33dfa2b08c65806c744b978a.jpg 640w, /wp-content/uploads/2017/09/c697a7cf33dfa2b08c65806c744b978a-300x200.jpg 300w, /wp-content/uploads/2017/09/c697a7cf33dfa2b08c65806c744b978a-207x138.jpg 207w" sizes="(max-width: 640px) 100vw, 640px" /></p>

<h2>Web Componentsの気になることを何でも聞いてみる</h2>

<p><b class="speaker siraisi">白石:</b> では、あとはWeb Componentsについて聞きたいことをいくつか用意してきたので、順に質問させてもらってもいいですか？</p>

<p><b class="speaker siraisi">泉水:</b> はい、お答えできることであれば何でも答えます。</p>

<p><b class="speaker siraisi">白石:</b> 例えば<strong>アクセシビリティ</strong>はいかがでしょうか。Web Componentsが広まると、たくさんの独自要素が開発者の手によって作られていくことになると思いますが、それでもアクセシビリティは担保できるものなのでしょうか。</p>

<p><b class="speaker siraisi">泉水:</b> それは問題にならないと予想しています。</p>

<p>Web Componentsの中身は、結局のところ一般的なHTML要素から構成されますので、そうした要素が持つセマンティクスなどをブラウザが活用することは可能です。また、アクセシビリティ情報を付与したければ、自作のコンポーネントにWAI-ARIAの属性などを指定していくこともできるでしょう。</p>

<p><b class="speaker siraisi">白石:</b> ReactやAngularなど、<strong>既存のフレームワークとWeb Componentsの関係</strong>はどうなりますか？うまく組み合わせて使っていけるものなのでしょうか？</p>

<p><b class="speaker siraisi">泉水:</b> 私もあらゆるフレームワークを知っているわけではありませんが、Reactに限って言うなら、組み合わせて使うことは難しくありません（筆者注: <a href="https://facebook.github.io/react/docs/web-components.html" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">Reactのドキュメントにも言及がある</a>）。</p>

<p>Reactのコンポーネントを、Shadow DOMにするのも難しくはないと思います。仮想DOMから実際のDOMをレンダリングする部分で、通常のDOMの代わりにShadow DOMを使えばいい。</p>

<p><img src="/wp-content/uploads/2017/09/e5c345982f3ab685b33276960a7285de.jpg" alt="" width="640" height="427" class="alignnone size-full wp-image-24298" srcset="/wp-content/uploads/2017/09/e5c345982f3ab685b33276960a7285de.jpg 640w, /wp-content/uploads/2017/09/e5c345982f3ab685b33276960a7285de-300x200.jpg 300w, /wp-content/uploads/2017/09/e5c345982f3ab685b33276960a7285de-207x138.jpg 207w" sizes="(max-width: 640px) 100vw, 640px" /></p>

<p><b class="speaker siraisi">白石:</b> そうすることによる利点には何があるでしょうか？</p>

<p><b class="speaker siraisi">泉水:</b> やはり、CSSがコンポーネントごとに分離できるのはうれしいですね。私はCSS Modulesとかがあまり好きではないので、標準的な仕組みでそれが行えるのであればすごく嬉しいです。</p>

<p><b class="speaker siraisi">白石:</b> CSSの分離という話でいうと、<strong>コンポーネントを使う側が、コンポーネント内のスタイルをカスタマイズしたい</strong>という要望は必ずあるかと思います。ですが、コンポーネントは基本的にスコープが閉じているので、外からスタイルを当てるのは工夫が必要ですよね。それについてはどう対応するのが正解なのでしょうか？</p>

<p><b class="speaker siraisi">泉水:</b> CSSカスタムプロパティを使うことですね。コンポーネント側では、使う変数名を決めておき、<code>var(--変数名, デフォルト値)</code>と指定して使用します。こうすれば、コンポーネントのデフォルト値でレンダリングはされつつも、呼び出し元で変数を指定すれば、コンポーネントのスタイルを上書きすることができます。<br>
（筆者注: Google Developersの文書に詳しく説明がある。<a href="https://developers.google.com/web/fundamentals/getting-started/primers/shadowdom?hl=ja#stylefromoutside" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">Shadow DOM v1: 自己完結型ウェブ コンポーネント</a>）</p>

<p><b class="speaker siraisi">白石:</b> ほか、最近Web Components周りで気になっている話題とかはありますか？</p>

<p><b class="speaker siraisi">泉水:</b> そうですね、コンポーネントの読み込みに関する部分はかなり気になるところです。</p>

<p>例えば、先程もコンポーネントをES Modulesで読み込むのが一般的になりそうだというお話をしましたが、一つ問題がありまして。<code>type='module'</code>を指定した<code>script</code>要素（筆者注: JavaScriptモジュール）って、デフォルトで<code>defer</code>で読み込まれる（※）ので、コンポーネントを宣言するJavaScriptの実行がどうしても遅くなってしまうんです。</p>

<p>なのでそうなると、<strong>コンポーネントを宣言するJavaScriptがロードされるまで、カスタム要素の中身がそのままレンダリングされちゃう</strong>っていう事態が発生してしまうんですよね。</p>

<p><small>
※script要素がdeferで読み込まれる…defer属性を指定されたscript要素は、レンダリングをブロックしないようにレンダリング処理と並列で読み込まれ、DOMContentLoaded終了後に実行される。
</small></p>

<p><img src="/wp-content/uploads/2017/09/2ac7fcb66c67ae7faf9d2b1d6e521b20.jpg" alt="" width="640" height="427" class="alignnone size-full wp-image-24300" srcset="/wp-content/uploads/2017/09/2ac7fcb66c67ae7faf9d2b1d6e521b20.jpg 640w, /wp-content/uploads/2017/09/2ac7fcb66c67ae7faf9d2b1d6e521b20-300x200.jpg 300w, /wp-content/uploads/2017/09/2ac7fcb66c67ae7faf9d2b1d6e521b20-207x138.jpg 207w" sizes="(max-width: 640px) 100vw, 640px" /></p>

<p><b class="speaker siraisi">白石:</b> おお、それは、先日<a href="https://html5experts.jp/shumpei-shiraishi/24207/" data-wpel-link="internal">ソフトバンク・テクノロジーの関口さんに伺ったWebフォントの話（「フォント素人のWebエンジニアが、「フォントおじさん」に聞いてみた！Webフォントの最近の事情とか」）</a>にも近いものがあるかもしれません。Webフォントの場合も、フォントファイルの読み込みが終わる前にシステムフォントでレンダリングされてしまうという問題があって、それをFONTPLUSでは独自に、該当要素を非表示にすることでちらつきを抑えているそうです。</p>

<p><b class="speaker siraisi">泉水:</b> 同様の対処が必要かもしれませんね。</p>

<p>あともう一つ、コンポーネントの読み込み周りで気になるところでいうと、HTML Importsならぬ<a href="https://github.com/w3c/webcomponents/issues/645" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">HTML Modulesっていう仕様が最近議論されていました</a>ね。これは、<code>import</code>にHTMLファイルを指定できるようにしようとするものです。</p>

<p><b class="speaker siraisi">白石:</b> それはなかなかアグレッシブなアイデアですね。ES Modulesで、コンポーネントのJavaScriptを読み込めるようにするというだけでは、やはりまだ満たせないものがあるということでしょうか。</p>

<p><b class="speaker siraisi">泉水:</b> やはり、ES Modulesだけだと、どうしてもJavaScriptが中心になってしまうんですよね。先程お見せしたコードでも、HTMLやCSSのコードを文字列としてコンポーネントが保持していました。でも、あれはそれほどいい方法とも思いません。マークアップやスタイリングを分業しやすいよう、JavaScriptファーストではない方法についても、検討の余地はまだまだあるということだと思います。</p>

<p><b class="speaker siraisi">白石:</b> なるほど、Web Compornentsの周りでも、まだまだ面白い展開が待ってそうですね。本日はいろんなことにお答えいただき、誠にありがとうございました！</p>
]]></content:encoded>
		
		<series:name><![CDATA[HTML5 Conference 2017特集]]></series:name>
	</item>
		<item>
		<title>進化するWeb Componentsの今、2016年最新情報</title>
		<link>/1000ch/21705/</link>
		<pubDate>Tue, 22 Nov 2016 00:00:40 +0000</pubDate>
		<dc:creator><![CDATA[泉水翔吾]]></dc:creator>
				<category><![CDATA[最新動向]]></category>
		<category><![CDATA[Web Components]]></category>

		<guid isPermaLink="false">/?p=21705</guid>
		<description><![CDATA[連載： 基礎からわかる Web Components 徹底解説 〜仕様から実装まで理解する〜 (7)Web Componentsが変えるWeb開発の未来から、はや二年が経ちました。コミュニティでの議論やフィードバックを経...]]></description>
				<content:encoded><![CDATA[<div class="seriesmeta">連載： <a href="https://html5experts.jp/series/web-components-2/" class="series-214" title="基礎からわかる Web Components 徹底解説 〜仕様から実装まで理解する〜" data-wpel-link="internal">基礎からわかる Web Components 徹底解説 〜仕様から実装まで理解する〜</a> (7)</div><p><a href="https://html5experts.jp/1000ch/8906/" data-wpel-link="internal">Web Componentsが変えるWeb開発の未来</a>から、はや二年が経ちました。コミュニティでの議論やフィードバックを経て2016年現在、Web Componentsの仕様は大きくアップデートされています。先日行われた<a href="http://gdg-tokyo.connpass.com/event/38927/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">DevFest Tokyo 2016</a>でも<a href="https://1000ch.github.io/slide/webcomponents-2016/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">Web Components 2016 &amp; Polymer v2</a> と題してWeb Componentsの最近についてお話しました。</p>

<p>これまでGoogleを中心に策定されてきたv0の仕様を元に、新しい仕様はMozillaやAppleなどの各ブラウザベンダーの合意を改めてとりながら策定が進められています。今日はアップデートされたWeb Componentsの仕様を説明していきます。</p>

<p><img src="/wp-content/uploads/2016/11/shadow-dom-640x588.png" alt="Shadow DOM" width="640" height="588" class="alignnone size-large wp-image-21715" srcset="/wp-content/uploads/2016/11/shadow-dom.png 640w, /wp-content/uploads/2016/11/shadow-dom-300x276.png 300w, /wp-content/uploads/2016/11/shadow-dom-207x190.png 207w" sizes="(max-width: 640px) 100vw, 640px" /></p>

<p>基本概念については割愛しますが、えーじさんの<a href="https://blog.agektmr.com/2014/11/shadow-dom-web-components.html" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">Shadow DOM &#8211; Web Componentsを構成する技術:Tender Surrender</a>と<a href="https://blog.agektmr.com/2014/11/custom-elements-web-components.html" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">Custom Elements &#8211; Web Componentsを構成する技術: Tender Surrender</a>がわかりやすいので、Shadow DOMやCustom Elementsが何なのかわからない人はまずこちらを見ましょう。</p>

<h2>Shadow DOM <strong>v1</strong>の仕様</h2>

<p>Shadow DOMはDOMにスコープをもたらす重要な仕様です。v1においては、基本的なコンセプトはそのままにAPIが見直されています。</p>

<h3>createShadowRoot()からattachShadow()へ</h3>

<p><code>createShadowRoot()</code> で行っていたShadow Rootの作成ですが、v1では <code>attachShadow()</code> を使います。関数がShadow Rootを返す点はこれまで同様です。</p>

<p></p><pre class="crayon-plain-tag">const div = document.querySelector('div');
const shadowRoot = div.attachShadow({
  mode: 'open' // or 'close'
});

// readonly な shadowRoot プロパティの追加
console.log(div.shadowRoot);</pre><p></p>

<p><code>attachShadow()</code> は引数にオプションを取ります。v1においてShadow DOMにはOpenedなモードとClosedなモードが存在し、<code>mode: 'open'</code> または <code>mode: 'close'</code> のように指定します。</p>

<p>Shadow DOMをホストできるHTML要素に <code>shadowRoot</code> という読み取り専用のプロパティが追加されており、要素のShadow DOMはこれを通して参照します。要素が Shadow DOMをホストした時点で <code>shadowRoot</code> プロパティは参照を返すようになり、Shadow DOMがないうちは <code>null</code> です。DevToolsで <code>document.querySelector('div').shadowRoot</code>を実行すると <code>undefined</code> ではなく <code>null</code> が（きっと）返ってきます。</p>

<h3>OpenedなShadow DOMとClosedなShadow DOM</h3>

<p>Shadow DOMのモードにOpenedとClosedがあることを先に述べましたが、これはShadow DOMの外の世界からアクセスできるかどうかを示します。このため、外部からアクセス不能なClosedなShadow DOMをホストする要素の <code>shadowRoot</code> プロパティは、<code>null</code> を返します。</p>

<p>外部からのアクセスを許すべきか封じるべきかは賛否両論があったため、この<strong>モード</strong>という形で合意形成されました。</p>

<p>ClosedなShadow DOMをホストする要素は第三者に編集されないので、コンポーネントを作ったときに独立性を保つことができます。ネイティブの <code>video</code> 要素を Chrome で閲覧すると、各種制御UIがShadow DOMで実装されていることがわかりますが、このように外部から操作されたくない場合にはClosedモードが適しているのでしょう。逆にOpenedでアクセスの余地を残せば、より柔軟にコンポーネントを利用できるはずです。</p>

<h3>複数Shadow Rootの廃止</h3>

<p>v0では単一の要素に対してShadow Rootを複数持つことが許可されていましたが、v1では禁止されます。そのため <code>attachShadow()</code> を2回以上実行すると例外が発生します。</p>

<h3>Shadow DOMをホストできる要素が限定的に</h3>

<p>v0ではあらゆる要素がShadow DOMをホストすることが可能でしたが、v1では限定的になります。許可が予定されているのは次の要素です。</p>

<p></p><pre class="crayon-plain-tag">article, aside, blockquote, body, div, footer, h1, h2, h3, h4, h5, h6, header, 
nav, p, section, span</pre><p></p>

<p>これらのネイティブ要素に加えて、カスタム要素もShadow DOMをホストできます。<code>input</code>や <code>img</code>などの置換要素がShadow DOMをホストできなくなるようです。</p>

<h3>Insertion PointsからSlotsへ</h3>

<p>カスタム要素で囲むコンテンツがどのように表示されるかは、カスタム要素に含まれる <code>content</code> 要素によって挿入先（Insertion Points）が決まっていました。v1では <code>slot</code> 要素によるSlotsに変わります。</p>

<p><code>form-container</code> というカスタム要素を例に解説します。</p>

<p></p><pre class="crayon-plain-tag">&lt;!-- v0での&lt;content&gt;によるInsertion Pointsの決定 --&gt;
&lt;template&gt;
  &lt;style&gt;
    ::content input {
      background: skyblue;
    }
  &lt;/style&gt;
  &lt;div&gt;
    &lt;content select=".class-name"&gt;&lt;/content&gt;
    &lt;content&gt;&lt;/content&gt;
  &lt;/div&gt;
&lt;/template&gt;

&lt;form-container&gt;
  &lt;input class="class-name" type="text"&gt;
  &lt;button&gt;Button&lt;/button&gt;
&lt;/form-container&gt;</pre><p></p>

<p><code>form-container</code> で囲まれた <code>input</code> と <code>button</code> は、それぞれ <code>form-container</code> の <code>content</code> に挿入されます。挿入先は <code>select</code> 属性に指定するセレクタで決定されていました。</p>

<p>v1からは次のように <code>slot</code> に置き換わります。<code>slot</code> は <code>name</code> 属性で命名可能で、カスタム要素を利用する側から能動的に指定できるようになります。</p>

<p></p><pre class="crayon-plain-tag">&lt;!-- v1での&lt;slot&gt;によるSlotsの決定 --&gt;
&lt;template&gt;
  &lt;style&gt;
    ::slotted(input) {
      background: skyblue;
    }
  &lt;/style&gt;
  &lt;div&gt;
    &lt;slot name="slot-name"&gt;&lt;/slot&gt;
    &lt;slot&gt;&lt;/slot&gt;
  &lt;/div&gt;
&lt;/template&gt;

&lt;form-container&gt;
  &lt;input slot="slot-name" type="text"&gt;
  &lt;button&gt;Button&lt;/button&gt;
&lt;/form-container&gt;</pre><p></p>

<p>に挿入された要素を参照する疑似セレクタも <code>::content</code> の子孫から、 <code>::slotted()</code> になっています。</p>

<h3>さらなる詳細について</h3>

<p>Shadow DOMのスペックエディタであるGoogleの夷藤さんの<a href="http://hayato.io/2016/shadowdomv1/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">What&#8217;s New in Shadow DOM v1 (by examples)</a>という記事を見ましょう。スペックに合わせて記事も随時アップデートされています。</p>

<h2>Custom Elements v1の仕様</h2>

<p>Custom Elementsは開発者が任意の要素を再定義可能にする、Shadow DOM同様に重要な機能です。</p>

<h3>ES2015 classベースの要素定義とライフサイクルコールバック</h3>

<p>Custom Elements v1ではES2015の <code>class</code> 記法を使った定義が推奨されます。もちろん <code>function</code> を使っても同等の実装は可能ですが、ブラウザのサポートも進みつつある <code>class</code> で書いていくのが望ましいでしょう。</p>

<p></p><pre class="crayon-plain-tag">&lt;!-- v0でのカスタム要素の定義 --&gt;
&lt;script&gt;
  const FooElement = Object.create(HTMLElement.prototype);
  FooElement.createdCallback = () =&gt; { ... };
  FooElement.attachedCallback = () =&gt; { ... };
  FooElement.detachedCallback = () =&gt; { ... };
  FooElement.attributeChangedCallback = () =&gt; { ... };

  document.registerElement('foo-element', {
    prototype: FooElement
  });
&lt;/script&gt;</pre><p></p>

<p>ライフサイクルコールバックも <code>class</code> の <code>constructor()</code> を活かしリネームされているほか、<code>adoptedCallback()</code> が追加されています。</p>

<p></p><pre class="crayon-plain-tag">&lt;!-- v1で推奨されるclassを使ったカスタム要素の定義 --&gt;
&lt;script&gt;
  class FooElement extends HTMLElement {
    constructor() { ... }
    connectedCallback() { ... }
    disconnectedCallback() { ... }
    attributeChangedCallback() { ... }
    adoptedCallback() { ... }
  }

  window.customElements.define('foo-element', FooElement);
&lt;/script&gt;</pre><p></p>

<p><code>adoptedCallback(oldDocument, newDocument)</code> はオーナーとなるドキュメントが変わったタイミングのハンドラです。同一のカスタム要素名が追加先のコンテキストで既に登録されている場合に、フォールバックするなどのユースケースがあるようです。</p>

<h3>window.customElements へ</h3>

<p>先に出ていますが、カスタム要素を定義する関数も <code>document.registerElement</code> から <code>customElements.define()</code> に変更されています。 <code>customElements</code> はブラウザコンテキストに追加される新たなグローバルオブジェクトです。</p>

<p><code>customElements.define()</code> の他には次のような関数が提案されています。</p>

<p></p><pre class="crayon-plain-tag">// &lt;foo-element&gt;コンストラクタを参照する
const FooElement = customElements.get('foo-element');

// &lt;foo-element&gt;が定義されたタイミングを取得する
customElements.whenDefined('foo-element').then(() =&gt; {
  console.log('foo-element is defined');
});</pre><p></p>

<p>カスタム要素は非同期で処理されるため、HTMLドキュメントに存在するカスタム要素の振る舞いは定義されるまでブラウザは知り得ません。そのため、ロードの遅延などと相まって意図しないガタツキなどを招きます。そのカスタム要素が他の要素をSlotsに追加するようなものであれば、影響はなおさら大きくなります。</p>

<p>それを防ぐには対象のカスタム要素が定義されるタイミングを知る必要があります。<code>customElements.whenDefined()</code> は指定のカスタム要素が定義されるタイミングをPromiseで知らせてくれます。これによって、初期表示ではカスタム要素を非表示にしておいて、ブラウザが評価可能になるタイミングで<code>display: none;</code> を外すといった対応も可能になるでしょう。</p>

<h3>Type Extensionの行方</h3>

<p><code>button is="foo-button"</code> のように、元の振る舞いを活かしつつ機能を拡張するType Extensionという機能がv0では検討されていました。この機能については<a href="https://github.com/w3c/webcomponents/issues/509" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">今なお議論が続けられています</a>。複雑な機能を持つ既存要素の振る舞いを壊さないような機能拡張の難しさへの懸念から反対意見も出ており、WebKitは実装を見送っています。行方が気になる人は引き続きウォッチしてみてください。</p>

<h2>HTML Imports</h2>

<p>HTML Importsについては<a href="https://hacks.mozilla.org/2014/12/mozilla-and-web-components/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">Mozillaが2014年に実装を見送っており</a>、昨年（2015年）においても<a href="https://hacks.mozilla.org/2015/06/the-state-of-web-components/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">引き続きES6 Modulesによるリソース解決が適切に動作するかどうかを見守る</a>姿勢を見せています。</p>

<h2>ブラウザサポート状況</h2>

<p>Shadow DOM v1とCustom Elements v1はChromiumにて先行実装されており、Shadow DOM v1はChrome 53とOpera 40から、Custom Elements v1はChrome 54とOpera 41から利用可能です。</p>

<p>またWebKitでも先行して進められており、Shadow DOM v1がSafari 10に実装されている他、Custom Elements v1もSafari Technology Preview 14に実装されており、メニューの<strong>Develop</strong> → <strong>Experimental Features</strong> → <strong>Custom Elements</strong>から有効化できます。</p>

<ul>
<li><a href="https://developer.apple.com/library/content/releasenotes/General/WhatsNewInSafari/Articles/Safari_10_0.html" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">Safari 10.0</a></li>
<li><a href="https://developer.apple.com/safari/technology-preview/release-notes/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">Safari Technology Preview Release Notes</a></li>
</ul>

<p>これらが意味するところは大きく、モバイルプラットフォームで大きなシェアを占めるSafariでサポートされることで、モバイルをターゲットとしているプロダクトではWeb Componentsの利用がかなり現実的になってきたと言えます。</p>

<p>デスクトップブラウザについてはFirefoxとEdgeで実装が進むを期待したいところです。EdgeはDeveloper Feedbackで<a href="https://wpdev.uservoice.com/forums/257854-microsoft-edge-developer/suggestions/6261298-custom-elements" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">Custom Elements</a>と<a href="https://wpdev.uservoice.com/forums/257854-microsoft-edge-developer/suggestions/6261298-custom-elements" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">Shadow DOM</a>に投票しておくと、早く実装してくれるかもしれません <img src="https://s.w.org/images/core/emoji/2.2.1/72x72/1f642.png" alt="🙂" class="wp-smiley" style="height: 1em; max-height: 1em;" /></p>
]]></content:encoded>
		
		<series:name><![CDATA[基礎からわかる Web Components 徹底解説 〜仕様から実装まで理解する〜]]></series:name>
	</item>
		<item>
		<title>モダンWeb：たった今と、ほんの少し未来のはなし～「de:code 2016」セッションレポート～</title>
		<link>/albatrosary/19092/</link>
		<pubDate>Wed, 25 May 2016 07:48:45 +0000</pubDate>
		<dc:creator><![CDATA[佐川 夫美雄]]></dc:creator>
				<category><![CDATA[最新動向]]></category>
		<category><![CDATA[Progressive Web Apps]]></category>
		<category><![CDATA[SPA]]></category>
		<category><![CDATA[Web Components]]></category>
		<category><![CDATA[de:code]]></category>

		<guid isPermaLink="false">/?p=19092</guid>
		<description><![CDATA[連載： de:code 2016 特集 (3)この記事は、「de:code2016」のセッションレポート、日本マイクロソフトエバンジェリスト物江修氏による「モダンWeb:たった今と、ほんの少し未来のはなし」です。講演内容...]]></description>
				<content:encoded><![CDATA[<div class="seriesmeta">連載： <a href="https://html5experts.jp/series/ms-decode2016/" class="series-371" title="de:code 2016 特集" data-wpel-link="internal">de:code 2016 特集</a> (3)</div><p>この記事は、「<a href="https://www.microsoft.com/ja-jp/events/decode/2016/default.aspx" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">de:code2016</a>」のセッションレポート、日本マイクロソフトエバンジェリスト物江修氏による「モダンWeb:たった今と、ほんの少し未来のはなし」です。講演内容を再現していますが、ニュアンス等伝えきれない場合があるかもしれません。ご了承ください。</p>

<h1>モダンWebとは</h1>

<p>昨今、様々なところで「モダンWeb」という言葉を聞くが、その定義は曖昧で意味するところの範囲が広範囲に及んでいるためではないかと考える。多くの場合、「モダンWeb」という文脈で語られている内容は次の４つの事柄で語られている。</p>

<ul>
<li>モダンなWebシステム</li>
<li>モダンな開発手法</li>
<li>モダンな標準機能</li>
<li>モダンなアプリケーション</li>
</ul>

<p><a href="https://html5experts.jp/wp-content/uploads/2016/05/DSC03848.jpg" data-wpel-link="internal"><img src="/wp-content/uploads/2016/05/DSC03848-640x480.jpg" alt="DSC03848" width="640" height="480" class="alignnone size-large wp-image-19104" srcset="/wp-content/uploads/2016/05/DSC03848.jpg 640w, /wp-content/uploads/2016/05/DSC03848-300x225.jpg 300w, /wp-content/uploads/2016/05/DSC03848-207x155.jpg 207w" sizes="(max-width: 640px) 100vw, 640px" /></a></p>

<p>単にモダンWebアプリケーションと言った場合にはこれらいろいろな意味に捉えることが多いが、このように四つに分けることができる。このセッションでは、アプリケーションを開発するのに必要な「モダンなWeb標準の機能」、「モダンなWebアプリケーション」に関して触れる。</p>

<h1>なぜ「モダンWeb」が話題になっているのか</h1>

<p>第一に挙げられることは「時代の要求」。具体的には以下の3つが挙げられる。</p>

<ul>
<li>Web技術の進化</li>
<li>コンテンツのリッチ化</li>
<li>クライアントの多様化</li>
</ul>

<p>Web技術で作るリッチなUIは昔から存在していたが、以前はFlashなどのプラグインを利用したいわゆるRIA(Rich Internet Applications)のほうが優勢だった。その後、Ajaxでデータを取得し、そのデータを使って部分的なUIの更新が可能になり、jQuery UIなどのUIライブラリによる開発生産性の向上、そしてHTML5の登場によって、プラグインで行っていたことがWebの標準技術だけで作ることが可能になった。これがWeb技術の進化である。</p>

<p>そしてスマートフォンから始まったFlashの衰退が進み、今までFlashで行っていたような要求をWebコンテンツ側にやってくるようになり、コンテンツのリッチ化が始まった。</p>

<p>スマートフォンを始め、PCブラウザー以外の様々なものがインターネットに繋がり、クライアントが多様化した。</p>

<p>この「クライアントの多様化」はサーバーサイドの形態にも影響を与え、その影響が、Webブラウザー上で動くアプリケーションにも影響を与えたという状況になっている。具体的にどういうことなのか。</p>

<p>黎明期のWebアプリケーションは、リクエストされたページを単純にレスポンスするというもの。ちなみに一番最初のWebサーバーはティム・バーナーズ・リーが作った「CERN Httpd」で、1991年にニュースグループで公開されたが、翌年に作られた「NCSA Httpd」ではCGIがサポートされ、動的ページが作れるようになった。ご存知の通り、このサーバーサイドで処理をして、処理結果をページで返すWebアプリケーションは広く使われている。</p>

<p>さらに、新しいクライアントとして携帯電話が現れる。NTT Docomoから始まった携帯電話は、それまでWebのクライアントというと、PCブラウザかゲーム機くらいで、いずれも机に座って使うようなものだった。</p>

<p>しかし、携帯電話は持ち歩き、行動に必要な情報を得るためのツールとして機能するモビリティという考え方が生まれた。</p>

<p>今までとは利用用途が異なる、サーバーではデバイスに応じた専用のコンテンツを作る必要があるなどコンテンツを作っていくには困難な状況だった。</p>

<p>やがて、スマートフォンに代表されるスマートデバイスが現れます。これらは、PCブラウザー用のコンテンツを同じ様に処理することができたので、わざわざ専用のコンテンツを用意しなくても済む。問題は、画面サイズに応じて表示を切り替える必要があり、同時期に出てきたHTML5関連技術であるCSS3を使ったレスポンシブWebデザインで、こうした技術を吸収することができた。</p>

<p>さらにスマートフォンは、サーバーサイドの処理にさらに大きな変化をもたらした。</p>

<p>Webアプリケーションの登場です。サーバにリクエストを投げるが、必要とするのはページではなくデータでした。この影響を受け、Webサーバーに必要な技術は、データを返す「API」が重要になった。</p>

<p>現在では、クライアントデバイスの性能とWebブラウザーの機能も数段上がり、処理性能ではネイティブで作られたアプリケーションと同等なことができるようになった。</p>

<h1>SPA(Single-page Application)</h1>

<p>単一ページによるWebアプリケーションであるSPAの特徴は、以下が挙げられる。</p>

<ul>
<li>画面遷移はDOM操作</li>
<li>ページのリフレッシュは不要</li>
<li>リッチなエクスペリエンス</li>
</ul>

<p>SPAにするメリットもいくつかある。例えば、サーバーサイドを「サービス化」することによって、多様化していくクライアントにも対応できるようになる。つまり、サービスをどこにでも提供できポータビリティを上げることができる。</p>

<p>現在のようにクライアント技術の進化が劇的に早い（言い換えると、陳腐化する速度も早い）状況下でもSPAは有効だ。クライアントとサーバーのロジックを物理的に別けることで保守性を上げることができるから。さらに分業においては、サーバーサイドを開発する人間、クライアントサイドを開発する人間で、やるべきことに集中できるということが挙げられる。</p>

<h1>プログラミングスタイルの変化</h1>

<p>SPAの登場によつてプログラミングのスタイルも少なからず変化している。Ajaxなどの非同期処理を行う場合、処理の単位はサーバーサイドの動作と必ずしも一致せず、処理の順番やタイミングもまちまちになる。それらを適切にハンドリングして画面に描画する必要がある。</p>

<p>さらに、ユーザーアクションの開始が、いわゆるPull型（サーバにリクエストするという意味で）だったが、WebRTCやWebSocketsの登場にによって、突発的に開始されるPush型（サーバからクライアントに通知する）可能性もある。</p>

<p>非同期処理の完了であるが JavaScriptではイベント通知で行われる。また、今まではサーバーロジックで行われていた処理をクライアントで行うケースも出てくるので、1つの完結する処理を行う場合、複数回サーバーとやり取りする必要がある。よく「コールバック地獄」ということに陥る。</p>

<p>不規則に発生するイベントを適切にルーティングしつつ、状態を把握し、かつ処理全体を制御する仕組みが必要で、こういった制御を行うために、JavaScriptのライブラリやフレームワークが様々な機能を実装し提供している。</p>

<p>そして、最新のモダンブラウザーがサポートしつつあるECMA Script2015や2016にも、こうした機能が標準で用意されようとしている。つまりイベントのフロー制御方法は</p>

<ul>
<li>Promise(ES2015)</li>
<li>async/await(ES2016)</li>
<li>Generator/yield(ES2015)</li>
</ul>

<p>Promiseは非同期処理を抽象化したオブジェクトでPromiseパターンで非同期処理を行う。async/awaitは、Promise とGeneratorの糖衣構文で、そのGenerator/yieldは、反復子 (イテレータ )の生成元で、実行環境を維持したま中断・再開が可能となる。</p>

<p>SPAでは画面のレンダリングも従来のサーバーサイドの処理をメインしたものとは異なる。</p>

<p>SPA以前のサーバーサイドでページが生成されるタイプのWebアプリケーションでは、画面データの成形もサーバーサイドで行われていましたが、SPAではその部分をクライアントサイドで行うことになる。</p>

<p>素直に書くなら、エレメント一つひとつのインスタンスを取得して、各々データをセットする所謂「Glue code」を書く（&#8221;グルー&#8221;とは糊のこと）ことになる。だが、これだとエレメント変更に関わるUI仕様があるたびにコードまで修正する必要がありメンテナンスが大変だし、いちいちデータを入れるためだけのコードを書くということ自体が非効率。</p>

<h2>データバインディング</h2>

<p>そこで出てきたのがUIへのデータバインドです。
マークアップにUIとデータの関係を記述しておくと、JavaScriptフレームワークがよしなにデータをセットしてくれるという仕組みです。
こうすることで、データと画面、いわゆる ModelとViewの関係を1:1に紐づけ、構造的には明確に分け部品化することが可能になった。</p>

<p>&#8220;バインド&#8221;とあるように、ModelとViewの関係を保持します。つまり、モデルもしくはビューに変更が発生した場合、その変更が一方向、あるいは双方向に反映されます。Modelの変更のみかViewに反映されるのが1Wayバインドで、双方向に変更が伝わるのが2Wayバインドです。</p>

<p>まとめるとモダンなWebアプリケーションとは</p>

<ul>
<li>SPA</li>
<li>リアクティブな動作</li>
<li>M-V-Whatever</li>
</ul>

<h1>少し先のWebアプリケーションの技術的コンセプト</h1>

<p>ここからは、ここ数年提唱されているWebアプリケーションの技術的コンセプトについて紹介します。</p>

<ul>
<li>Web Components</li>
<li>Progressive Web Apps</li>
<li>WebAssembly</li>
</ul>

<h2>Web Components</h2>

<p>まずは「Web Components」です。これはWebをコンポーネント化する仕組みで、2013年のGoogle I/Oで紹介された。実は、Webをコンポーネント化するという仕組みは、これが最初ではなく、マイクロソフトも1998年にHTMLコンポーネントというものを提案したし、Mozillaも2001年にXBLと2007年にXBL2というのを提案した。</p>

<p>このコンポーネント化のメリット、目的について</p>

<p>Webのアプリケーションは、他のソフトウェア・アプリケーションと同様に複雑になり、今ではリリース製品の開発に大勢が協力して取り組むことは珍しくなくなった。少しでも効率化を図るには、関係者やシステム間の重複が最小限になるように開発作業を分割する正しい方法を見つけることが重要になる。そのための方法としてコンポーネント化がある。複雑なシステムでも、機能を分割していけば、単純化することができる。全体をある程度の機能単位に分割する、つまりはコンポーネント化だ。</p>

<p>Web Componentsの目標は、HTML、CSS、JavaScriptの関連グループを分離し、単一ページのコンテキスト “内” で共通関数を実行することで、複雑さを軽減することだ。</p>

<p>この Web Components は、複数の API を組み合わせるか、それ単独を使用して実現する。
しかし、すべての Web ブラウザーがその API をサポートしているわけではないので、Polyfill 用のライブラリーが用意されています。</p>

<p>そしてこちらがWeb Componentsを構成する要素です。</p>

<ul>
<li>HTML Templates</li>
<li>Shadow DOM</li>
<li>Custom Elements</li>
<li>HTML Imports</li>
</ul>

<p>現在のサポートの状況はこのようになっています。</p>

<table>
<thead>
<tr>
  <th>Web Components</th>
  <th>Edge 13</th>
  <th>Chrome 50</th>
  <th>Firefox 45</th>
  <th>Safari 9.1</th>
</tr>
</thead>
<tbody>
<tr>
  <td>HTML Templates</td>
  <td>○</td>
  <td>○</td>
  <td>○</td>
  <td>×</td>
</tr>
<tr>
  <td>Shadow DOM</td>
  <td>× Medium</td>
  <td>○</td>
  <td>△※</td>
  <td>×</td>
</tr>
<tr>
  <td>Custom Elements</td>
  <td>× High</td>
  <td>○</td>
  <td>△※</td>
  <td>×</td>
</tr>
<tr>
  <td>HTML Imports</td>
  <td>× Low</td>
  <td>○</td>
  <td>△※</td>
  <td>×</td>
</tr>
</tbody>
</table>

<p>※ 既定では動作しない</p>

<h2>Progressive Web Apps</h2>

<p>これはモバイル Web アプリ向けのコンセプトで、具体的には、高性能のモバイルWebブラウザー向けにネイティブアプリケーションのようなUXを提供しようというも。去年の「Chrome Dev Summit」のキーノートで発表され話題になったものだ。今年の４月に行われた「Google Developers Summit Tokyo 2016」でも2日のテーマになっていたくらい力を入れている。</p>

<p>Progressive Web Appsに求められる体験をまとめると次の様なもの</p>

<ul>
<li>ネイティブアプリケーションのようなUX

<ul>
<li>オフラインサポート: Service Worker</li>
<li>プッシュ通知: Web Notifications/Push API</li>
<li>ホームスクリーンにアイコンの追加: Web App Manifest</li>
<li>バックグラウンド: Service Worker</li>
<li>高速でなめらかなインターフェース: CSS3 Animation</li>
</ul></li>
</ul>

<p>Service Workerは、JavaScriptで実装されているローカルのプロキシ、あるいはApplication Cacheの改良版として利用できる。
いままで Web ブラウザーからサーバーにコンテンツをリクエストする場合、サーバーになげてそれを返していたのが、その間にカスタマイズ可能な Service Worker というのが入って
バックグラウンドで動いているので、タブを閉じてもブラウザを終了しても動作しているので、プッシュ通知もうけとれるとこと。httpsでしか動作しない。</p>

<p>Progressive Web Appsを実現する技術のサポート状況は</p>

<table>
<thead>
<tr>
  <th>Edge</th>
  <th>Chrome</th>
  <th>Firefox</th>
  <th>Safari</th>
</tr>
</thead>
<tbody>
<tr>
  <td>Internal build</td>
  <td>Canary 51.0.2677.0</td>
  <td>Nightly</td>
  <td>&#8211;</td>
</tr>
</tbody>
</table>

<h3>WebAssenbly</h3>

<p>WebAssenblyは、コンパイル済みのバイナリをWebブラウザ上で直接動作させる仕組で、Microsoft、Google、Mozilla、Webkitプロジェクトのメンバーで共同開発されていて足並みが揃っている。</p>

<p>JavaScriptよりもポータブルでロード時間や実行に対するパフォーマンスに優れたアプリケーションを作ることが可能だ。asm.jsの次のステップとしている。</p>

<p>2016/3/14〜16の間にMicrosoft、Google、Mozillaの3社が3Dゲーム<a href="http://webassembly.github.io/demo/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">Angry bot</a>での検証結果を各ブログで公開している。</p>

<p>WebAssemblyの実装状況は</p>

<table>
<thead>
<tr>
  <th>WebAssembly</th>
  <th>Edge 13</th>
  <th>Chrome 50</th>
  <th>Firefox 45</th>
  <th>Safari 9.1</th>
</tr>
</thead>
<tbody>
<tr>
  <td>Service Workers</td>
  <td>× High</td>
  <td>○</td>
  <td>○</td>
  <td>×</td>
</tr>
<tr>
  <td>Fatch API</td>
  <td>△ Preview</td>
  <td>○</td>
  <td>○</td>
  <td>×</td>
</tr>
<tr>
  <td>Web Notifications</td>
  <td>△ Preview</td>
  <td>○</td>
  <td>○</td>
  <td>×</td>
</tr>
<tr>
  <td>Push API</td>
  <td>× High</td>
  <td>○</td>
  <td>○</td>
  <td>×</td>
</tr>
<tr>
  <td>Web Application Manifest</td>
  <td>検討中</td>
  <td>○</td>
  <td>○</td>
  <td>×</td>
</tr>
</tbody>
</table>

<h2>ハイブリッドアプリケーションとしての利用</h2>

<p>Webアプリケーションが苦手とするところは</p>

<ul>
<li>ストアのエコシステムを利用しない</li>
<li>Webブラウザからはどうしてもアクセスできないハードウェアリソース</li>
</ul>

<p>そしてこれらの Web アプリケーションのは、ハイブリットアプリとしてパッケージすることにより、ターゲットとなるプラットフォームのリソースや、ブラウザーからはアクセスできないハードウェアの機能を使用できるようになる。
また、アプリストアのエコシステムを利用することができる。</p>

<h2>Webフロントエンドの開発リソース</h2>

<p>インタラクティブなコンテンツを作ることができるようになったので、開発は非常に大変なものになった。</p>

<ul>
<li>JavaScript

<ul>
<li>ライブラリ</li>
<li>フレームワーク</li>
<li>エンジンテンプレート</li>
<li>altJS</li>
</ul></li>
<li>CSS

<ul>
<li>フレームワーク</li>
<li>プリプロセッサー</li>
</ul></li>
<li>HTML

<ul>
<li>軽量マークアップ</li>
</ul></li>
<li>パッケージマネージャ</li>
<li>タスクランナー</li>
<li>モジュール管理</li>
</ul>

<p>Richになったことで多くのライブラリが提供された結果「Chaos」になったのか？と思いがち。そして、ライブラリ/フレームワークの選定として考える必要がある。</p>

<ul>
<li>ブラウザサポート</li>
<li>ベンダーサポート</li>
<li>情報

<ul>
<li>ドキュメント</li>
<li>書籍類</li>
</ul></li>
<li>学習コスト</li>
<li>開発生産性</li>
<li>機能範囲</li>
<li>ロックイン</li>
<li>運用コスト</li>
</ul>

<p>特にこの中のロックインですが、ロックインは決して悪いものではなく、優秀なベンダーと一緒になってやっていくこと、コミュニティの力を借りることでむしろ良い状況も作れる。運用コストに関しては、便利なんだけどお金がかかるというものについては考えもの。</p>

<h2>標準技術は不変</h2>

<p>結局、Webブラウザで動作するのは、HTML、CSS、JavaScriptであり、ブラウザがサポートしていない機能は動かない。技術はあくまでも「手段」でり、そうした技術に対する勉強は大事だが、手段であって目的ではない。目的は、ユーザに対して良いプロダクトを提供すること。たとえば、YouTubeはFlashで作られていたが、HTML5に変わったことに気づいた人はいない、そういうものが良い。</p>

<p>そして、WebはApplicationのプラットフォームになる。どんどん低レベルなAPIを実装することになる。結果、デスクトップと同じ様なアプリケーションを作っていける。こうした変貌は「変化」ではなく「拡張」である。</p>
]]></content:encoded>
		
		<series:name><![CDATA[de:code 2016 特集]]></series:name>
	</item>
		<item>
		<title>Polymer v1.1のAPIまとめと周辺リソースの紹介</title>
		<link>/1000ch/17410/</link>
		<pubDate>Thu, 29 Oct 2015 01:06:17 +0000</pubDate>
		<dc:creator><![CDATA[泉水翔吾]]></dc:creator>
				<category><![CDATA[最新動向]]></category>
		<category><![CDATA[Polymer]]></category>
		<category><![CDATA[Web Components]]></category>

		<guid isPermaLink="false">/?p=17410</guid>
		<description><![CDATA[連載： 基礎からわかる Web Components 徹底解説 〜仕様から実装まで理解する〜 (6)Googleが開発するWeb ComponentsのライブラリPolymerのバージョン1.1が、2015年8月13日に...]]></description>
				<content:encoded><![CDATA[<div class="seriesmeta">連載： <a href="https://html5experts.jp/series/web-components-2/" class="series-214" title="基礎からわかる Web Components 徹底解説 〜仕様から実装まで理解する〜" data-wpel-link="internal">基礎からわかる Web Components 徹底解説 〜仕様から実装まで理解する〜</a> (6)</div><p>Googleが開発するWeb Componentsのライブラリ<a href="https://www.polymer-project.org/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">Polymer</a>のバージョン1.1が、2015年8月13日にリリースされました。本記事では、Polymer v1.1のAPIの主要なAPIを解説しつつ、その参考情報を紹介していきます。</p>

<p>また、この記事は「<a href="https://html5experts.jp/1000ch/14400/" data-wpel-link="internal">Web ComponentsのこれからーPolymer 0.8、X-Tag、Brick、Bosonic</a>」を事前に読むと理解が深まりますが、これからPolymer v1.1を始めてみるということであれば、本記事単体でも参考にしてもらえればと思います。</p>

<h1>Polymer v1.1までの変更点</h1>

<p>v0.5からv0.8にかけての差分は<a href="https://html5experts.jp/1000ch/14400/" data-wpel-link="internal">前回の記事</a>にて紹介しましたが、その1週間後にv0.9がリリースされ、さらに2週間後にv1.0がリリースされています。</p>

<ul>
<li><a href="https://blog.polymer-project.org/updates/2015/03/27/why-0.8/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">0.8 released! &#8211; polymer blog</a></li>
<li><a href="https://blog.polymer-project.org/announcements/2015/05/14/0.9-release/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">0.9 released! &#8211; polymer blog</a></li>
<li><a href="https://blog.polymer-project.org/announcements/2015/05/29/one-dot-oh/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">1.0 &#8211; polymer blog</a></li>
<li><a href="https://blog.polymer-project.org/announcements/2015/08/13/1.1-release/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">1.1 Release &#8211; polymer blog</a></li>
<li><a href="https://www.polymer-project.org/1.0/docs/migration.html" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">Migration guide</a></li>
</ul>

<p>v0.8からv1.0にかけてAPIに変更が加えられていますが、v1.0からv1.1へかけては破壊的なAPIの変更はありません。今回は以降で、Polymer v1.x系の主な機能と、参考リソースの紹介をしていきます。</p>

<p><img src="/wp-content/uploads/2015/10/polymer-project-640x541.png" alt="polymer-project" width="640" height="541" class="alignnone size-large wp-image-17419" srcset="/wp-content/uploads/2015/10/polymer-project.png 640w, /wp-content/uploads/2015/10/polymer-project-300x254.png 300w, /wp-content/uploads/2015/10/polymer-project-207x175.png 207w" sizes="(max-width: 640px) 100vw, 640px" /></p>

<h2>カスタム要素の登録</h2>

<p>&lt;dom-module&gt; に &lt;template&gt; と &lt;script&gt; を記述して宣言します。 &lt;script&gt; 内で実行している<code>Polymer()</code>関数は、 &lt;dom-module&gt; に指定しているID（カスタム要素の名前）を渡し、その他の引数でカスタム要素の振る舞いを決定します。返り値にはカスタム要素のコンストラクタが返却されるので、それを使ってカスタム要素のインスタンスを生成することも可能です。</p>

<p></p><pre class="crayon-plain-tag">&lt;link rel="import" href="bower_components/polymer/polymer.html"&gt;

&lt;dom-module id="my-element"&gt;

  &lt;template&gt;
    &lt;style&gt;
      div { color: red; }
    &lt;/style&gt;
    &lt;div&gt;Shadow DOM in My Element&lt;/div&gt;
  &lt;/template&gt;

  &lt;script&gt;
    var MyElement = Polymer({is: 'my-element'});
  &lt;/script&gt;

&lt;/dom-module&gt;</pre><p></p>

<p>v0.8との違いは、カプセル化されるカスタム要素のスタイルを記述する &lt;style&gt; と、<code>Polymer</code>関数を実行する &lt;script&gt; を &lt;dom-module&gt; の中に書くようになった点です。v0.5までの &lt;polymer-element&gt; を彷彿させます。v1.1では &lt;template&gt; の外側に &lt;style&gt; を書いてもスタイルが適用されますが、パフォーマンスは悪く推奨されません。</p>

<h3>カスタムコンストラクタ</h3>

<p>カスタム要素のコンストラクタを自前で書きたい場合は、<code>Polymer()</code>関数の引数として、<code>factoryImpl</code>キーワードと共にコンストラクタ関数を渡します。カスタムコンストラクタによって、引数を渡すことが可能になります。</p>

<p></p><pre class="crayon-plain-tag">&lt;script&gt;
  var MyElement = Polymer({
    is: 'my-element',
    factoryImpl: function(foo, bar) {
      // custom constructor is called
    }
  });

  var myInstance = new MyElement('foo', 100);
&lt;/script&gt;</pre><p></p>

<p>この<code>factoryImpl</code>はコンストラクタ関数（ここでは<code>MyElement</code>）を<code>new</code>キーワードと共呼び出した場合のみ実行され、HTMLドキュメントで &lt;my-element&gt; が評価された場合には呼ばれません。</p>

<h3>ネイティブ要素の継承</h3>

<p>ネイティブ要素を継承したカスタム要素を作る場合は、<code>Polymer()</code>関数の引数に<code>extends</code>キーワードに継承するネイティブのHTML要素を指定します。v0.5まではカスタム要素の継承もサポートされていましたが、Custom Elementsの仕様として<code>document.registerElement()</code>にカスタム要素名を渡せないのと同様、ブラウザネイティブの要素（<code>input</code>や<code>button</code>など）のみを指定できるようになっています。</p>

<p></p><pre class="crayon-plain-tag">&lt;script&gt;
  var MyElement = Polymer({
    is: 'my-element',
    extends: 'button'
  });
&lt;/script&gt;</pre><p></p>

<p>ネイティブ要素を拡張するカスタム要素を使うには、<code>extends</code>に指定した要素にカスタム要素名を<code>is</code>属性に指定します。JavaScriptからインスタンスを生成する場合は、コンストラクタを<code>new</code>するか、<code>document.registerElement()</code>の第二引数にカスタム要素名を指定してください。</p>

<p></p><pre class="crayon-plain-tag">&lt;button is="my-element"&gt;My Element&lt;/button&gt;

&lt;script&gt;
  console.log(new MyElement() instanceof HTMLButtonElement);
  // =&gt; true
  console.log(document.createElement('button', 'my-element') instanceof HTMLButtonElement);
  // =&gt; true
&lt;/script&gt;</pre><p></p>

<h3>ライフサイクルコールバック</h3>

<p>カスタム要素には4つのライフサイクルが存在し、Polymerでもそれらをハンドリングできます。ライフサイクルについては<a href="https://html5experts.jp/1000ch/11142/" data-wpel-link="internal">Web Componentsを構成する4つの仕様 ー Web Components基礎編</a>という記事の「カスタム要素の挙動を設定する」をセクションにて解説しています。ブラウザネイティブでは<code>createdCallback</code>・<code>attachedCallback</code>・<code>detachedCallback</code>、<code>attributeChangedCallback</code>の4つが定義されていますが、Polymerでは<code>Callback</code>が省略されている他、<code>ready</code>というShadow Root配下のDOM構築が完了したタイミングで発火されるハンドラも定義できるようになっています。</p>

<p></p><pre class="crayon-plain-tag">&lt;script&gt;
  Polymer({
    is: 'my-element',
    created: function () {
      console.log('my-elementが生成されました');
    },
    attached: function () {
      console.log('my-elementがHTMLドキュメントに追加されました');
    },
    detached: function () {
      console.log('my-elementがHTMLドキュメントから切り離されました');
    },
    attributeChanged: function (name, type) {
      console.log('my-elementの' + name + '属性が変更されました');
    },
    ready: function () {
      console.log('my-elementのDOM構築が完了しました');
    }
  });
&lt;/script&gt;</pre><p></p>

<p>ハンドラの実行順序をまとめると以下のようになります。</p>

<ol>
<li><code>created</code>コールバック</li>
<li><code>ready</code>コールバック</li>
<li><code>factoryImpl</code>コールバック</li>
<li><code>attached</code>コールバック</li>
<li>(<code>detached</code>コールバック)</li>
</ol>

<h3><code>behaviors</code>を使った振る舞いの制御</h3>

<p>カスタム要素の振る舞いを制御するには、これまでのように<code>Polymer()</code>に直接ハンドラなどを指定するほか、<code>behaviors</code>にプロトタイプとなるようなオブジェクトを渡すことでも可能です。オブジェクトで定義できるのは先程登場したライフサイクルコールバック、後述するデフォルト属性やプロパティ、オブザーバー（<code>observer</code>）、イベントハンドラの登録（<code>listener</code>）です。</p>

<p></p><pre class="crayon-plain-tag">&lt;script&gt;
var MyBehavior = {
  ready: function() {
    console.log('DOM is ready');
  }
};

Polymer({
  is: 'my-element',
  behaviors: [MyBehavior]
});
&lt;/script&gt;</pre><p></p>

<p>見ての通り、<code>behaviors</code>にはオブジェクトを配列で指定することが可能です。複数指定されてハンドラが重複する（例えば、複数のオブジェクトで<code>ready</code>が定義されている）場合は、配列上で後から出現するオブジェクトが優先されます（つまり右辺が優先されます）。</p>

<h2>カスタム要素のデフォルト属性</h2>

<p>カスタム要素のデフォルト属性は、引数の<code>hostAttributes</code>に定義します。<code>hostAttributes</code>に指定した属性とその値は、カスタム要素の属性のデフォルト値になります。</p>

<p></p><pre class="crayon-plain-tag">&lt;script&gt;
  var MyElement = Polymer({
    is: 'my-element',
    hostAttributes: {
      role: 'navigation'
    }
  });
&lt;/script&gt;</pre><p></p>

<p>この時 &lt;my-element&gt; は、デフォルトで &lt;my-element role=&quot;navigation&quot;&gt;&lt;/my-element&gt; として評価されます。</p>

<h2>カスタム要素のプロパティ</h2>

<p>カスタム要素のプロパティは、引数の<code>properties</code>に定義します。プロパティ名をキーに、<code>type</code>や<code>value</code>などの属性を渡すことでプロパティの特徴を定義します。簡略化された形としては、<code>propertyName: type</code>という指定も可能です</p>

<p></p><pre class="crayon-plain-tag">&lt;script&gt;
  Polymer({
    is: 'my-element',
    properties: {
      foo: {
        type: Number,
        value: 0,
        observer: 'fooChanged'
      }
      bar: {
        type: String,
        computed: 'computeBar(foo)'
      }
    }
    fooChanged: function(newValue, oldValue) {
      // ...
    },
    computeBar: function(foo) {
      return String(foo + 100);
    }
  });
&lt;/script&gt;</pre><p></p>

<p>ここでは<code>foo</code>と<code>bar</code>の2つを<code>my-element</code>のプロパティとして定義していますが、それぞれ<code>observer</code>と<code>computed</code>という属性を渡しています。</p>

<h3>オブザーバー関数を指定する<code>observer</code></h3>

<p><code>observer</code>はプロパティの変更を監視するオブザーバー関数を指定する属性です。ここでは<code>fooChanged</code>という関数を定義しているので、関数名を文字列で渡しています。v0.5までは<code>propertyNameChanged</code>といったような命名規則を用いてオブザーバー関数を定義していましたが、v1.1においてその機能はありません。監視する関数には引数として、変更後の値（<code>newValue</code>）と変更前の値（<code>oldValue</code>）が引数と渡されるので、前後値を利用することができます。</p>

<h3>コンピュート関数を指定する<code>computed</code></h3>

<p><code>computed</code>はプロパティの値を動的に算出するための関数を指定する属性です。<code>observer</code>同様に関数名を文字列で渡しますが、ここでは<code>bar</code>プロパティに対し<code>computeBar(foo)</code>という値を渡しています。この記述によって<code>computeBar</code>関数には<code>foo</code>プロパティが引数として渡され、<code>bar</code>の値は関数が返却する値を参照します。</p>

<h3>HTML属性に反映するかどうかを指定する<code>reflectToAttribute</code></h3>

<p>プロパティの値に変更があっても通常はHTML属性に反映されませんが、<code>reflectToAttribute</code>に<code>true</code>を指定するとHTMLの属性も更新されるようになります。</p>

<p></p><pre class="crayon-plain-tag">&lt;script&gt;
  Polymer({
    is: 'my-element',
    properties: {
      foo: {
        type: String,
        reflectToAttribute: true
      }
    },
    ready: function() {
      this.foo = 'Hello!';
      // this.setAttribute('foo', 'Hello!');と同等の振る舞いが得られる
    }
  });
&lt;/script&gt;</pre><p></p>

<p>この時、<code>ready</code>の関数が実行されたタイミングで &lt;my-element&gt;&lt;/my-element&gt; は &lt;my-element foo=&quot;Hello!&quot;&gt;&lt;/my-element&gt; となり、<code>setAttribute('foo', 'Hello!')</code>を実行したときと同様の振る舞いが得られます。</p>

<h2>イベントハンドラの登録</h2>

<p>v0.5以前まではイベントハンドラの登録をブラケットを使って宣言的に定義していましたが、v1.1からはブラケットを使わなくなった他、<code>listeners</code>プロパティにイベントとそのハンドラをハッシュ形式で定義が可能です。</p>

<p></p><pre class="crayon-plain-tag">&lt;dom-module id="my-element"&gt;

  &lt;template&gt;
    &lt;button on-click="clickHandler"&gt;Button&lt;/button&gt;
  &lt;/template&gt;

  &lt;script&gt;
    var MyElement = Polymer({
      is: 'my-element',
      listeners: {
        'tap': 'myElementTapHandler'
      },
      clickHandler: function(e, detail) {
        // button click handler
      },
      myElementTapHandler: function(e, detail) {
        // my-element tap handler
      }
    });
  &lt;/script&gt;

&lt;/dom-module&gt;</pre><p></p>

<h3>ジェスチャーイベントのハンドリング</h3>

<p>先程のサンプルで<code>tap</code>というDOMネイティブには存在しないイベントに対して<code>myElementTapHandler</code>というハンドラを登録していますが、Polymerは自前で実装するにはやや面倒な4つのイベントをサポートしています。</p>

<ul>
<li><code>down</code>: マウスや指によって要素が押下された時</li>
<li><code>up</code>: マウスや指が押下後に離された時</li>
<li><code>tap</code>: <code>down</code>と<code>up</code>が連続して発生した時</li>
<li><code>track</code>: マウスや指が押下されたまま移動した時</li>
</ul>

<p>それぞれのイベントのハンドラに渡されるイベント引数の<code>detail</code>プロパティには様々な付加情報が渡されます。詳しくは<a href="https://www.polymer-project.org/1.0/docs/devguide/events.html#gestures" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">公式ドキュメント</a>を確認してください。</p>

<h3>カスタムイベントの発火</h3>

<p><code>fire</code>という関数を実行することで、ホスト要素を呼び出し元オブジェクトとしてカスタムイベントを発行することが出来ます。引数にはカスタムイベント名と、ハンドラの<code>detail</code>プロパティに渡すデータを指定します。</p>

<p></p><pre class="crayon-plain-tag">&lt;dom-module id="my-element"&gt;

  &lt;template&gt;
    &lt;button on-click="clickHandler"&gt;Button&lt;/button&gt;
  &lt;/template&gt;

  &lt;script&gt;
    var MyElement = Polymer({
      is: 'my-element',
      clickHandler: function(e, detail) {
        this.fire('foo', {
          bar: 100
        });
      }
    });
  &lt;/script&gt;

&lt;/dom-module&gt;

&lt;my-element&gt;&lt;/my-element&gt;

&lt;script&gt;
  var myElement = document.querySelector('my-element');
  myElement.addEventListener('foo', function(e) {
    console.log(e.detail.bar);
    // =&gt; 100
  });
&lt;/script&gt;</pre><p></p>

<p>ここでは &lt;my-element&gt; のボタンをクリックした時に<code>foo</code>というカスタムイベントを発行し、付加データとして<code>{ bar: 100 }</code>という値を渡しています。</p>

<h2>データバインディング</h2>

<p>データバインディングは以前と同様にカーリーブラケット<code>{{}}</code>およびスクエアブラケット<code>[[]]</code>で指定します。ブラケットではプロパティおよびコンピュート関数を評価することが可能で、v0.5まで有効だった演算子などはサポートされていません。</p>

<p></p><pre class="crayon-plain-tag">&lt;dom-module id="my-element"&gt;

  &lt;template&gt;
    &lt;input value="{{foo}}" type="text"&gt;
    &lt;input value="[[bar]]" type="text"&gt;
  &lt;/template&gt;

  &lt;script&gt;
    Polymer({
      is: 'my-element',
      properties: {
        foo: String,
        bar: Number
      }
    });
  &lt;/script&gt;

&lt;/dom-module&gt;</pre><p></p>

<p>ここでは&lt;my-element&gt;のプロパティとして定義している<code>foo</code>や<code>bar</code>を、 &lt;input&gt; の<code>value</code>にバインディングしています。これによって<code>foo</code>や<code>bar</code>の値に変更があると、&lt;input&gt;に自動で反映されます。</p>

<h3>カーリーブラケット<code>{{}}</code>とスクエアブラケット<code>[[]]</code></h3>

<p>カーリーブラケット<code>{{}}</code>とスクエアブラケット<code>[[]]</code>の差は、データバインディングの方向が一方向に制限されるかどうかの違いです。<code>{{}}</code>のデータバインディングは双方向か一方向かが記述によって変わりますが、<code>[[]]</code>は一方向のみであり参照しているプロパティを受け取るのみです。</p>

<p>カーリーブラケット<code>{{}}</code>で指定した際にバインディングの振る舞いを決定するのは、プロパティの<code>notify</code>フラグと<code>readOnly</code>フラグです。</p>

<p></p><pre class="crayon-plain-tag">&lt;script&gt;
  Polymer({
    is: 'my-element',
    properties: {
      foo: {
        type: String,
        notify: true
      },
      bar: {
        type: Number,
        readOnly: true
      }
    }
  });
&lt;/script&gt;</pre><p></p>

<p><code>notify</code>フラグはプロパティの変更をホスト要素に通知するかどうか、<code>readOnly</code>フラグはプロパティが読み取り専用かどうかを決定します。この例では<code>notify: true</code>なので、 &lt;my-element foo=&quot;{{value}}&quot;&gt;&lt;/my-element&gt; としたときに<code>foo</code>に変更があると<code>value</code>へ値が反映されます。</p>

<h3>ネイティブ要素との双方向データバインディング</h3>

<p>ネイティブ要素との双方向データバインディングも <strong>target-prop=&quot;{{hostProp::target-change-event}}&quot;</strong> という構文でサポートしています。ここでは&lt;input&gt;に入力された値に括弧を付与して&lt;div&gt;に埋め込んでいます。</p>

<p></p><pre class="crayon-plain-tag">&lt;dom-module id="my-element"&gt;

  &lt;template&gt;
    &lt;input value="{{foo::input}}" type="text"&gt;
    &lt;div&gt;{{computeBar(foo)}}&lt;/div&gt;
  &lt;/template&gt;

  &lt;script&gt;
    Polymer({
      is: 'my-element',
      properties: {
        foo: {
          type: String
        }
      },
      computeBar: function(foo) {
        return `「${foo}」`;
      }
    });
  &lt;/script&gt;

&lt;/dom-module&gt;</pre><p></p>

<p>入力された値を参照するタイミングは<code>input</code>イベントで、バインドするホストプロパティは<code>foo</code>なので、 <strong>input value=&quot;{{foo::input}}&quot;&gt;</strong> になります。これによって、ネイティブ要素のプロパティからカスタム要素へのプロパティへのデータバインディングが行われます。</p>

<h3>属性とのデータバインディング</h3>

<p>属性に対してデータをバインディングするには以下のように<code>$=</code>を使い、ブラケット<code>{{}}</code>にはこれまでと同様にカスタム要素のプロパティやコンピュート関数を記述します。</p>

<p></p><pre class="crayon-plain-tag">&lt;template&gt;
  
  &lt;!-- Attribute binding --&gt;
  &lt;my-element selected$="{{value}}"&gt;&lt;/my-element&gt;
  &lt;!-- results in &lt;my-element&gt;.setAttribute('selected', this.value); --&gt;

  &lt;!-- Property binding --&gt;
  &lt;my-element selected="{{value}}"&gt;&lt;/my-element&gt;
  &lt;!-- results in &lt;my-element&gt;.selected = this.value; --&gt;
  
&lt;/template&gt;</pre><p></p>

<p>プロパティとのデータバインディングには &lt;my-element foo={{value}}&gt; と記述することで<code>document.querySelector('my-element').foo = value</code>を振る舞いますが、HTMLの属性にバインディングするためには &lt;my-element foo$={{value}}&gt; のように<code>$=</code>で指定することで <code>document.querySelector('my-element').setAttribute('foo', value)</code> が動的に実行されます。</p>

<p>ネイティブの属性である<code>class</code>や<code>style</code>には、次のように<code>$=</code>でバインディングすることが可能です。</p>

<p></p><pre class="crayon-plain-tag">&lt;!-- class --&gt;
&lt;div class$="{{foo}}"&gt;&lt;/div&gt;

&lt;!-- style --&gt;
&lt;div style$="{{background}}"&gt;&lt;/div&gt;

&lt;!-- href --&gt;
&lt;a href$="{{url}}"&gt;

&lt;!-- label for --&gt;
&lt;label for$="{{bar}}"&gt;&lt;/label&gt;

&lt;!-- dataset --&gt;
&lt;div data-bar$="{{baz}}"&gt;&lt;/div&gt;</pre><p></p>

<p>HTML上の属性名とDOMのプロパティ名が異なる場合には留意が必要でしょう。data-*の場合、<code>data-foo</code>への実際のプロパティは<code>element.dataset.foo</code>となるため、<code>data-foo={{bar}}</code>ではバインディングできず、<code>element.setAttribute('data-foo', bar)</code>となる<code>data-foo$={{bar}}</code>を使う必要があります。</p>

<h3>Templateのリピート</h3>

<p>配列のデータは &lt;template is=&quot;dom-repeat&quot;&gt; を使ってリピートし、要素ひとつひとつを参照することが出来ます。以下は<code>is="dom-repeat"</code>を使って配列を展開しているサンプルです（公式より引用）。</p>

<p></p><pre class="crayon-plain-tag">&lt;dom-module id="employee-list"&gt;

  &lt;template&gt;
    &lt;div&gt; Employee list: &lt;/div&gt;
    &lt;template is="dom-repeat" items="{{employees}}"&gt;
      &lt;div&gt;# &lt;span&gt;{{index}}&lt;/span&gt;&lt;/div&gt;
      &lt;div&gt;First name: &lt;span&gt;{{item.first}}&lt;/span&gt;&lt;/div&gt;
      &lt;div&gt;Last name: &lt;span&gt;{{item.last}}&lt;/span&gt;&lt;/div&gt;
    &lt;/template&gt;
  &lt;/template&gt;

  &lt;script&gt;
    Polymer({
      is: 'employee-list',
      ready: function() {
        this.employees = [
          {first: 'Bob', last: 'Smith'},
          {first: 'Sally', last: 'Johnson'}
        ];
      }
    });
  &lt;/script&gt;

&lt;/dom-module&gt;</pre><p></p>

<p>&lt;template is=&quot;dom-repeat&quot;&gt; に加えて展開したい配列を<code>items</code>属性で指定します。配列の要素の数だけ &lt;template &gt; の内部が繰り返されますが、この中では要素を表す<code>item</code>と配列のインデックスを示す<code>index</code>という二つの変数を参照できます。</p>

<p><code>items</code>で参照している配列に変更を加える場合には、インスタンスの関数をそのまま使うのではなくPolymerのインスタンスが備えている専用の関数を使います。例えばこのサンプルの<code>employees</code>に値を追加する場合は、 <code>this.employees.push({...})</code>ではなく<code>this.push('employees', {...})</code>とする必要があります。<code>push</code>の他には<code>pop</code>、<code>splice</code>、<code>shift</code>、<code>unshift</code>も同様です。これらの関数を使わないと、配列への変更が検知されずに再描画されません。</p>

<p>Polymerのデータバインディングの更なる詳細については<a href="https://www.polymer-project.org/1.0/docs/devguide/data-binding.html" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">Data binding &#8211; Polymer 1.0</a>を参照してください。</p>

<h2>Polymer内部で行うDOM操作</h2>

<p>&lt;dom-module&gt;内部のDOMの操作を行う場合は、Shadow RootのDOM APIではなく専用のインターフェースが用意されています。</p>

<h3>IDが与えられている要素の参照</h3>

<p>要素に対してIDが与えられていると、<code>this.$.id</code>という形で自動的に参照が生成されます。これはv0.5まで存在していた機能なので、馴染みのある人もいるかと思います。</p>

<p></p><pre class="crayon-plain-tag">&lt;dom-module id="my-element"&gt;

  &lt;template&gt;
    This is my-element &lt;span id="foo"&gt;&lt;/span&gt;!
  &lt;/template&gt;

  &lt;script&gt;
    Polymer({
      is: 'my-element',
      ready: function() {
        this.$.foo.textContent = this.foo;
      }
    });
  &lt;/script&gt;

&lt;/dom-module&gt;</pre><p></p>

<p>また、動的に生成された要素を参照する場合は<code>this.$$(selector)</code>という関数が用意されています。これにCSSセレクタを渡すと、セレクタにマッチする最初の要素が返却されます。</p>

<h3><code>Polymer.dom()</code>を使ったDOM操作</h3>

<p>Polymer内部のDOM操作を行う場合は、Shadow Root配下の要素のDOM APIを直接実行するのではなく、<code>Polymer.dom()</code>という専用のAPIが用意されています。<code>Polymer.dom()</code>の引数にはNodeを渡し、返却されるオブジェクトには、ネイティブのDOM APIと同等の振る舞いをするAPIが用意されています。いずれもDOMのAPIと同じ命名と引数で設計されていますが、サブセットとして用意されているに過ぎず、完全に互換性があるわけではないことに注意してください。</p>

<h4>親子関係</h4>

<ul>
<li><code>Polymer.dom(parent).childNodes</code></li>
<li><code>Polymer.dom(node).parentNode</code></li>
<li><code>Polymer.dom(node).firstChild</code></li>
<li><code>Polymer.dom(node).lastChild</code></li>
<li><code>Polymer.dom(node).firstElementChild</code></li>
<li><code>Polymer.dom(node).lastElementChild</code></li>
<li><code>Polymer.dom(node).previousSibling</code></li>
<li><code>Polymer.dom(node).nextSibling</code></li>
<li><code>Polymer.dom(node).textContent</code></li>
<li><code>Polymer.dom(node).innerHTML</code></li>
</ul>

<h4>クエリ</h4>

<ul>
<li><code>Polymer.dom(parent).querySelector(selector)</code></li>
<li><code>Polymer.dom(parent).querySelectorAll(selector)</code></li>
</ul>

<h4>コンテンツの参照</h4>

<ul>
<li><code>Polymer.dom(contentElement).getDistributedNodes()</code></li>
<li><code>Polymer.dom(node).getDestinationInsertionPoints()</code></li>
</ul>

<h4>属性の操作</h4>

<ul>
<li><code>Polymer.dom(node).setAttribute(attribute, value)</code></li>
<li><code>Polymer.dom(node).removeAttribute(attribute)</code></li>
<li><code>Polymer.dom(node).classList</code></li>
</ul>

<p><code>Polymer.dom</code>から行う追加や削除といったDOM操作は、パフォーマンスを考慮し遅延して実行するようになっています。そのため、操作後のノードの座標やgetComputedStyle()を使ったスタイルの取得をする場合は、操作を<code>Polymer.dom.flush()</code>を使って適時実行し、反映します。</p>

<h2>カスタム要素のスタイリング</h2>

<p>CSSのスタイリングは、これまでと同様にShadow DOMをスタイリングする記法が適用されます。PolymerはShadow DOMの実装状況で振るまいが変わらないように、Shady DOMという軽量なポリフィルを採用しているため、CSSセレクタをネイティブと同様に書くことはできません。</p>

<p>例えば、&lt;content&gt;を参照する<code>::content</code>セレクタです。Shadow DOMがブラウザネイティブに実装されていれば単一でも評価されるはずですが、Shady DOMの互換性として<code>::content</code>セレクタには何らかの親セレクタを指定する必要があります。これは <strong>::content .bar</strong> と記述された場合にShady DOMで実現しているスコープを再現できなくなるためです。この場合、 <strong>.foo &gt; ::content .bar</strong> と書く必要があり、実際には <strong>.foo &gt; .bar</strong> のように評価されます。</p>

<p></p><pre class="crayon-plain-tag">&lt;dom-module id="my-element"&gt;

  &lt;template&gt;
    &lt;style&gt;
      :host {
        display: block;
        border: 1px solid red;
      }
      .foo &gt; ::content .bar {
        background: orange;
      }
    &lt;/style&gt;

    &lt;div class="foo"&gt;&lt;content&gt;&lt;/content&gt;&lt;/div&gt;
  &lt;/template&gt;
  
  &lt;script&gt;
    Polymer({
      is: 'my-element'
    });
  &lt;/script&gt;

&lt;/dom-module&gt;</pre><p></p>

<h2>まとめ</h2>

<p>Polymer v1.1の主な機能について解説しました。v0.5 → v0.8 → v0.9 → v1.0&#8230;とAPIに多くの変更が加えられてきましたが、メジャーリリースになったことで、これまでのような大きな変更は（ <strong>おそらく</strong> ）なくなるでしょう。</p>

<p>最後に、今年9月の14日〜15日にオランダのアムステルダムにて開催された<a href="https://www.polymer-project.org/summit" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">Polymer Summit 2015</a>にて、参考リソースが多く公開されたのでそれを紹介します。</p>

<h3>Polymer Codelabs</h3>

<p><a href="http://www.code-labs.io/polymer-summit" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">Polymer Codelabs</a>は、Polymerを使ったアプリケーションを作成していくチュートリアル集です。Polymer Summitに合わせて11個のチュートリアルが公開されています。こちらも英語ですが、環境のセットアップから丁寧に解説されています。</p>

<h3>セッション動画リスト</h3>

<p>Polymer Summit 2015の各セッションはすべて以下のチャンネルで配信されていますので、興味のある方は是非チェックしてみてください。</p>


<!-- iframe plugin v.4.3 wordpress.org/plugins/iframe/ -->
<iframe width="560" height="315" src="https://www.youtube.com/embed/jVn8tlnwAEs?list=PLNYkxOF6rcICdISJclfQhj2S8QZGjXV8J" frameborder="0" 0="allowfullscreen" scrolling="yes" class="iframe-class"></iframe>

]]></content:encoded>
		
		<series:name><![CDATA[基礎からわかる Web Components 徹底解説 〜仕様から実装まで理解する〜]]></series:name>
	</item>
		<item>
		<title>【エキスパートガチトーク】Web技術の未来を「Extensible Web」から探る！（後編）─技術の進化は必要か？</title>
		<link>/shumpei-shiraishi/16641/</link>
		<pubDate>Tue, 08 Sep 2015 01:00:19 +0000</pubDate>
		<dc:creator><![CDATA[白石 俊平]]></dc:creator>
				<category><![CDATA[最新動向]]></category>
		<category><![CDATA[Extensible Web]]></category>
		<category><![CDATA[Promise]]></category>
		<category><![CDATA[ServiceWorker]]></category>
		<category><![CDATA[Web Components]]></category>

		<guid isPermaLink="false">/?p=16641</guid>
		<description><![CDATA[本対談記事は、Extensible Webが誕生してから2年で何が変わったのか、そしてこれからWebはどうなっていくのかを、有識者の方々にそれぞれの立場から語っていただこうという企画です。 後編である今回は、Extens...]]></description>
				<content:encoded><![CDATA[<p><style>
.post-detail-contents p {
  text-indent: 0;
  clear: left;
}
b.speaker.komatsu {
  background: url('/wp-content/uploads/2015/08/komatsu.png') no-repeat;
  background-size: 48px;
}
b.speaker.shiraishi {
  background: url('/wp-content/uploads/2015/08/shiraishi.png') no-repeat;
  background-size: 48px;
}
b.speaker.saito {
  background: url('/wp-content/uploads/2015/08/saito.png') no-repeat;
  background-size: 48px;
}
b.speaker.daniel {
  background: url('/wp-content/uploads/2015/08/daniel.png') no-repeat;
  background-size: 48px;
}
b.speaker.asai {
  background: url('/wp-content/uploads/2015/08/asai.png') no-repeat;
  background-size: 48px;
}
b.speaker {
  display: inline-block;
  width: 48px;
  height: 18px;
  float: left;
  padding-right: 8px;
  padding-top: 48px;
  text-align: center;
  font-size: 12px;
  margin-bottom: 4px;
  font-weight: normal;
  clear: left;
}
p {
  overflow: hidden;
}
</style>
本対談記事は、<strong>Extensible Web</strong>が誕生してから2年で何が変わったのか、そしてこれからWebはどうなっていくのかを、有識者の方々にそれぞれの立場から語っていただこうという企画です。</p>

<p>後編である今回は、Extensible Webの現在、そしてWeb技術の未来にフォーカスしたお話になります。Extensible Webの概要や、Extensible Web以前からあるWebの問題点について知りたい方は、<a href="https://html5experts.jp/shumpei-shiraishi/16597/" data-wpel-link="internal">前編</a>をご覧ください。</p>

<p><img src="/wp-content/uploads/2015/08/DSC_0187.png" alt="" width="640" height="407" class="aligncenter size-full wp-image-16716" srcset="/wp-content/uploads/2015/08/DSC_0187.png 640w, /wp-content/uploads/2015/08/DSC_0187-300x191.png 300w, /wp-content/uploads/2015/08/DSC_0187-207x132.png 207w" sizes="(max-width: 640px) 100vw, 640px" /></p>

<h2>HTML5は（ついに）モジュール化される</h2>

<p><b class="speaker shiraishi">白石</b> では、Extensible Webの考え方が提唱されてから2年が過ぎたわけですが、どのような変化が起きつつありますか？まずは皆さん、思いついたものから教えていただけると嬉しいです。</p>

<p><b class="speaker daniel">ダニエル</b> 最近の話で言うと、<strong>HTML5の仕様がモジュール化されます</strong>。例えば<a href="http://w3c.github.io/charter-html/timed-media-wg.html" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">Timed Media Working Group</a>というワーキンググループが提案されていますが、もともとはHTML5の一部でした。このように、専門的なグループに分かれて仕様策定が進められるようになろうとしています。</p>

<p><b class="speaker shiraishi">白石</b> Extensible Webは、標準化の話とも密接に関わっているかと思うので、詳しく教えて下さい。HTML5.1がバラバラになっていくということでしょうか？</p>

<p><b class="speaker daniel">ダニエル</b> そうです。まだ詳細は決まっていませんが、<strong>今後仕様書も分割されていきます</strong>。ちょうど、CSSがバージョン3になって、多数の仕様書に分割されて、それぞれメンテナンスされるようになったのと似た感じになるでしょう。</p>

<p>また、ワーキンググループが分かれていくというだけではなく、もっと開発者が参加しやすくなります。その一つが、<a href="https://www.w3.org/community/wicg/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">Web Incubator Community Group</a>の作成です。これができたのもつい最近（2015/7/2）ですね。ここは仕様を提案する場というよりは、質問してアドバイスを受けたり、デモを投稿したりと、一般の開発者のサポートが中心になります。</p>

<p><b class="speaker saito">斉藤</b> これは素晴らしいですね。最近すごく思うのは、仕様書がGitHubに置かれるようになって、<strong>別にGitHubが大好きというわけでもないんですが、開発者に見られるサイトNo.1ということで</strong>、変更の履歴すらも簡単に見られるようになり、どういう経緯で仕様が変更されていったかが追えるようになったのは素晴らしいと思います。</p>

<p><b class="speaker daniel">ダニエル</b> 10月のTPACまでに細かい作業を終えて、TPAC以降にフィードバックをもらいながら改善していくという感じだと思います。</p>

<h2>APIの低レベルさはどこまで許容される？</h2>

<p><b class="speaker asai">浅井</b> 最近はExtensible Webの流れを受けて、低レベルなAPIを提供して開発者に使ってもらおう、ということを意識するようになりました。例えば最近、センサー類のAPIを作ろうとしているのですが、大きく２つの方向性があるという議論になったんですよ。</p>

<p>一つは光センサーとか、既存のセンサーを抽象化するようなもの。またそれと合わせて、組み込み向けの通信制御のAPIを提供してはどうかというものでした。こちらはまあ、普通ですね。</p>

<p>でももう一つはぶっ飛んでて、<strong>Low Level File System APIっていうのを作ってしまってはどうか</strong>、と。
UNIXって、<code>/dev</code> 以下のファイルを通じてデバイスにアクセスできるじゃないですか。だったら、ファイルにアクセスできる手段を一つ開発者に与えてあげるだけで、どんなデバイスでも操作できるようになるじゃないか、と。本当に低レベルなものを作りさえすれば、開発者が必要なものを作れるよという考え方です。</p>

<p>でもこれは完全にぶっ飛んでる。だってプラットフォームに思い切り依存するじゃないですか。やり過ぎ感はすごくあるけど(笑)、それをマジメに議論できるようになったというのが、Extensible Webから来る発想なんじゃないかな、という気がします。僕としては、ちょっと低レベルすぎるんじゃないかと思いますが。</p>

<p><b class="speaker shiraishi">白石</b> そのうち、システムコールとか叩けるAPIが出てきそうですね。</p>

<p><b class="speaker asai">浅井</b> あまりAPIが低レベル過ぎても、今度は（JavaScriptライブラリによる）パフォーマンスのロスが大きすぎるし、OS依存のAPIを露出するのはよくないという考え方もあるので、どこまで低レベルにいくべきかというのは、今Extensible Webの中で本当に議論していかなくてはならないんじゃないか、という気がします。</p>

<h2>「Extensible」なAPIたち</h2>

<p><b class="speaker shiraishi">白石</b> なるほど。ではここでちょっと話を変えて、実際にExtensible Webに関連するAPIといえば何があるんでしょう？まず<strong>Fetch</strong>（※）とか。あと、<strong>ServiceWorker</strong>（※）もでしょうか。</p>

<p><b class="speaker saito">斉藤</b> <strong>Promise</strong>（※）とかもそうだと言っていいんじゃないでしょうか。Promiseの原型になったAPI（Deferとか）は、Extensible Webの提唱以前からありますが。</p>

<p><b class="speaker komatsu">小松</b> 他には、<strong>Object.observe</strong>（※）とかもありますね。</p>

<p><b class="speaker asai">浅井</b> <strong>Web Components</strong>（※）もそうでしょうね。</p>

<p><b class="speaker daniel">ダニエル</b> Web Componentsは便利ですよね。Polymer 1.0が出た時に使ってみましたが、とてもよかった。でも、Polymer自体がものすごく巨大なので、便利さの代償も大きいな、と(笑)。</p>

<p><b class="speaker asai">浅井</b> Web Components、小規模なプロジェクトならいいですが、大規模で長期的なプロジェクトとかでは、まだあまり使われてないんじゃないでしょうか。
そういう点では、Mozillaはむしろ積極的に使っています。しかも、Firefox OS本体で。<strong>本当に大事なAPIは、誰かがガチで使わないと熟成されないので、我々は必ず本番プロジェクトにガンガン入れるんです</strong>。</p>

<p>Firefox OS 2.5とかになると、Web ComponentsだけじゃなくてServiceWorkerとかも思い切り使って、アプリケーションのアーキテクチャを大幅に変更しようとしてます。どこよりもServiceWorkerを思い切り使って、悪いところを見つけ出そう、くらいの勢いですね。
ただ、ServiceWorkerをフルに使用して、複雑なキャッシュ処理とかを行うコードを見ていると、これはもう一般のWeb開発者が気軽に触れるレベルじゃないな、と思います。WebGLを生で扱うコードとかもそうですけど。</p>

<p><img src="/wp-content/uploads/2015/08/DSC_0175.png" alt="" width="640" height="426" class="aligncenter size-full wp-image-16719" srcset="/wp-content/uploads/2015/08/DSC_0175.png 640w, /wp-content/uploads/2015/08/DSC_0175-300x200.png 300w, /wp-content/uploads/2015/08/DSC_0175-207x138.png 207w" sizes="(max-width: 640px) 100vw, 640px" /></p>

<p><b class="speaker komatsu">小松</b> WebRTCなんかについても、「一般のWeb開発者にとっては、使うのが難しい」という話はよく聞きます。でも<strong>WebRTCは、低レベルすぎるという意見もあれば、あれでもまだAPIのレベルが高過ぎるという意見もあって</strong>。</p>

<p>もともとはビデオチャットをユースケースとしてAPIを作っていたんだけど、実際にやってみると双方向のビデオチャットだけじゃなくて、例えば監視カメラみたいに「一方向だけ」というユースケースも重要だったりとか、多人数会議とかやるときは映像のネゴシエーションとかもっと柔軟にやりたい、という話が出てくると、実は今のWebRTCでも高レベルすぎると。その議論が、今のORTCに繋がったりしているわけです。しかし、APIのレベルを低くすればするほど、柔軟性は向上するんだけど取り扱いは難しくなって、一般の開発者が触るには難しいものになっていくだろうな…とは感じています。</p>

<p><b class="speaker shiraishi">白石</b> なるほど…WebRTCみたいな、高度なネットワーク処理を伴うAPIについては、TCP/UDPのソケットを直接触れるような低レベルAPIがあればよさそうですよね。Socket APIとかは既にあるんでしたっけ？</p>

<p><b class="speaker asai">浅井</b> ありますよ。Firefox OSではよく使われています。</p>

<p><b class="speaker shiraishi">白石</b> ああそうか、Firefox OSやChrome OSだと、かなり低レベルなJavaScript APIが既に実装されてますよね。Bluetoothとか、シリアル通信とかも可能だったような。</p>

<p><b class="speaker daniel">ダニエル</b> BluetoothのAPIは使ってみたんですけど、やっぱりChromeブラウザじゃなくてChrome OSでしか使えないんですよね。ブラウザで（通常のWebアプリで）使いたいとは感じましたが、それは叶っていません。「危険だ」と。</p>

<p><b class="speaker komatsu">小松</b> <strong>APIのレイヤーを下げていくことと、セキュリティやプライバシーはトレードオフがあります</strong>よね。</p>

<p><small>
※ Fetch…ブラウザがHTTPを使用してリソースを取得する操作をAPIとして利用できるようにしたもの。XMLHttpRequestに近いが、よりAPIが洗練されている</p>

<p>※ ServiceWorker…バックグラウンドで動作し、アプリケーションのHTTPリクエスト・レスポンスをフック可能なAPI。詳しくは<a href="https://html5experts.jp/iwase/7006/" data-wpel-link="internal">こちらの記事</a>を参照のこと。</p>

<p>※ Promise…JavaScriptの非同期処理を扱いやすくするAPI。いわゆる「コールバック地獄」から開放される。</p>

<p>※ Object.observe…オブジェクトのプロパティ変更を監視できるAPI。AngularJSなどでユースケースが発見され、標準化提案がなされている。</p>

<p>※ Web Components…カスタム要素を利用できるようにできるAPI
</small></p>

<h2>低レベルAPIとセキュリティ・プライバシー</h2>

<p><b class="speaker daniel">ダニエル</b> 今お話に上がったように、「低レベルなAPIは危ない」という問題もある。皆さんここはどう考えますか？</p>

<p><b class="speaker shiraishi">白石</b> 僕が今回の対談を準備するにあたって、いろいろ情報を集めた中では、「<strong>そういうセキュリティやプライバシーの部分こそ、標準化のリソースを費やすべき点だ</strong>」という意見がありました。ひとりのエンジニアが、自分の力だけでセキュリティやプライバシーを完璧に実装することは不可能なので、標準化というプロセスを踏んで様々な知見を集約することで、そういったAPIの安全性を担保するという。</p>

<p><b class="speaker asai">浅井</b> ただ今の時代、<strong>APIだけでセキュリティを担保するのは難しくて、結局はアプリケーションのエコシステム全体でサポートしていかなくちゃいけない</strong>んですよね。例えばWebを全てHTTPS化するとか、アプリケーションマーケットでセキュリティレビューが行われるから安全になるとか、ほかの仕組みと組み合わせることで安全性を担保するという形になってきている。</p>

<p>まあ、一方で、そういう他の仕組みで担保してもらえるからエンジニア自身はあまりセキュリティのことを考えなくなっている…というのもあると感じています。もし低レベルのAPIが使えるようになるなら、実際躊躇なく開発者は使うわけですよ。Firefox OSでもふんだんに使われています。セキュリティレビュー前提でね。でも、そのセキュリティレビューが、どのエコシステムでも行われるわけではない。もしそういうAPIが、（セキュリティレビューのない）一般のWebコンテンツでも使えるようになったらまずいんです。</p>

<p><strong>エコシステム全体で安全性を保っているのに、エコシステム抜きでAPIだけ持ってきて使えるようにしてしまうと、安全でなくなってしまう。そこをどうやって担保していけばいいのか</strong>な、というのはすごく難しく感じています。</p>

<p><b class="speaker shiraishi">白石</b> HTTPSが前提だったり、Firefox OSみたいな環境の上でサンドボックス化されたアプリケーションであることが前提だったりとか、APIを取り囲む様々なコンテキストだったり環境を含めてこそセキュリティが担保されるのであって、APIだけ切り出して安全性を担保するというのは難しいということですね。</p>

<p><b class="speaker saito">斉藤</b> なるほど… 正直、「ServiceWorkerがHTTPSのみになりました」と聞いた時「なんだとコノヤロウ」と思ったくらいなんですが(笑)。よくよく考えてみると「そうだよね」と納得は出来るんですが、一方で「誰がそのSSL証明書代払うねん」という感じでもあります(笑)。</p>

<p><b class="speaker asai">浅井</b> <a href="http://www.mozilla.jp/blog/entry/10442/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">MozillaはHTTPSの無料化を推進しようとしています</a>けどね。</p>

<p><b class="speaker shiraishi">白石</b> そうですよね、頑張ってくださいよMozillaさん！世界中がMozillaに期待してます(笑)！</p>

<p>でも、ServiceWorkerはHTTPSオンリーです、というのは少し乱暴な感じも受けるのですが。<strong>今後、Extensible Webの思想に則ったAPIがどんどん現れるとして、「とりあえず危ないかもしれないからHTTPS限定にしておこう」という感じになっちゃわないんでしょうか</strong>？</p>

<p><b class="speaker saito">斉藤</b> まあ、流れとしてはWebは全部HTTPSにしていこうという感じですしねえ…</p>

<p><b class="speaker komatsu">小松</b> そうそう。iOS9のWebViewは、<a href="http://dev.classmethod.jp/smartphone/iphone/ios-9-intro-ats/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">デフォルトではHTTPS接続しかできなくなるしね</a>。</p>

<p><b class="speaker daniel">ダニエル</b> 標準化のほうでも、実際そういう流れはあります。「<a href="https://w3c.github.io/webappsec/specs/powerfulfeatures/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">Secure Contexts</a>」というドキュメントがあって、<a href="https://w3c.github.io/webappsec/specs/powerfulfeatures/#threat-risks" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">「こういう場合はHTTPS接続が必要」というシチュエーションを列挙しています</a>。
これによると、センシティブなデータやセンサーデータにアクセスするAPIは全て対象となっていますので、（今まで非HTTPS環境でも利用できていた）<strong>Geolocation APIなども、将来的にはHTTPS限定になるかもしれません</strong>。</p>

<h2>世界は、開発者からのフィードバックを求めている</h2>

<p><b class="speaker shiraishi">白石</b> ここまでは、Extensible Webを中心として、Webの過去や現在についてお話いただきました。では、<strong>未来のWeb技術はどうなるんでしょう</strong>？</p>

<p><b class="speaker daniel">ダニエル</b> 簡単に言うと、<strong>低レベルなAPIが増えて、高レベルなライブラリが増える</strong>、ってことじゃないかと思います。</p>

<p><b class="speaker saito">斉藤</b> 一般の開発者や企業もライブラリを作るようになり、もっと言えば、それで利益を上げる企業が出てきてもいいと思います。今はWebのプラットフォームやライブラリを作っているのって、結局ブラウザベンダ周辺の方々ばかりです。もしそこで利益を上げられる仕組みが出てきたとしたら、もっと一般の企業や開発者がWebのプラットフォームづくりに貢献できるようになるんじゃないかと。今は、あまり貢献できる余地がない。</p>

<p><b class="speaker asai">浅井</b> <strong>（Webプラットフォームへの）貢献という点では、ブラウザベンダの立場から言うと、一番求めているのって開発者からのフィードバックなんですよね</strong>。Webブラウザのエンジニアは、フィードバックが欲しくてしかたがないんですよ。自分たちが仕様を書いても、他の人が作って使ってくれないと標準化できないんですから。そこを、どんな方法でもいいから解決したくって、だからこそこんな考え方（Extensible Web）になったという流れもあると思います。</p>

<p><b class="speaker shiraishi">白石</b> そうですよねえ…前編でいくつか挙がっていた「使われていないAPI」なんて、ほんとに使われてなさそうなので、フィードバックも何もあったもんじゃないですよね。</p>

<p><b class="speaker asai">浅井</b> そうなんです。少なくとも僕らは、W3Cにインパクトを与えるためにもどんどん開発者は意見をあげていってほしいと思っていますし、ダニエルさんが紹介していたWeb Platform Incubator Groupにも参加してほしいと思っています。Mozillaに限って言えば、<strong>Bugzillaに日本語でもいいからガンガンコメント欲しい</strong>ですね。「英語で書かなくちゃならない」と思って書かない方も多いんですが、翻訳サイトを使って読んでみて、わからなければ日本のエンジニアに質問が来るので。</p>

<p><b class="speaker saito">斉藤</b> なるほど、そういう貢献であれば、気軽にできそうだし人にも促せそうです。</p>

<p><b class="speaker asai">浅井</b> <strong>わかりにくい英語でフィードバックもらうくらいなら、専門用語満載で日本語で書いてくれたほうがありがたい</strong>んです。フィードバックをもらえないことで発生するコストに比べたら、日本語のフィードバックをもらってそれに日本のスタッフが応えるなんて安いもんです。今はそれこそ、縦書きの仕様とかあるじゃないですか。ああいうところって、日本でしか通用しない用語がたくさんある。それを無理に英語にする必要はなくて、そのまま日本語で書いてほしい。</p>

<p><b class="speaker saito">斉藤</b> そうですよね…「禁則処理」とか英語でどう言えばいいのか、よく考えたら知らない(笑)。</p>

<p><b class="speaker asai">浅井</b> そういうフィードバックを世界中の開発者がくれる、という未来を僕らは目指しているんです。それに、Extensible Webが進むことで、例えばライブラリやミドルウェアをビジネスにするような企業も出てきたとしたら、そういう企業ってブラウザベンダとの協業にも本気なので、更にフィードバックが熱くなって嬉しいし。</p>

<p>例えば3Dにしても、UnityとかUnrealとか大きな企業がガンガンフィードバックをくれるので、WebGLやasm.jsも —— 今は WebAssemblyの方向に向かっていますが —— どんどんよくなっていったわけですし。</p>

<p><b class="speaker komatsu">小松</b> 確かに、ビジネスで使われると急激にフィードバックが貰えるようになりますよね。</p>

<p><b class="speaker saito">斉藤</b> 「趣味」のレベルと「ビジネス」のレベルだと、フィードバックするモチベーションもぜんぜん違うかもしれませんね。</p>

<p><b class="speaker komatsu">小松</b> そうそう。趣味でやってる時って、例えバグに遭遇したとしても「このバグは仕様である」って済ませちゃう(笑)。</p>

<p><b class="speaker saito">斉藤</b> 「ま、いっか」で済ませちゃいますよね(笑)。Web技術の進化がビジネスに直結するのであれば、フィードバックのモチベーションは確実に高まると思います。</p>

<h2>今あえて問う: Web技術の進化は求められているのか？</h2>

<p><b class="speaker shiraishi">白石</b> ここで一つ、ちょっと刺激的に聞こえるかもしれない問題提起をさせてください。
<strong>Web技術の進化って、今そんなに求められているのでしょうか？</strong>
現状で言うと、Web技術って主にデスクトップブラウザで使われていて、モバイルはネイティブでいいよね、と世間に認知されている感覚が僕としてはあって。
しかも、デスクトップは進化が停滞していて、イノベーションはモバイルアプリで起こっている。WebのAPIをどんどん拡充していっているけど、それで喜んでいる人ってどれくらいいるのかな？と。</p>

<p><b class="speaker daniel">ダニエル</b> 確かに…最近そういう議論がありましたね。<a href="https://twitter.com/ppk" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">ppk</a>（※）を中心として、<a href="http://www.quirksmode.org/blog/archives/2015/07/stop_pushing_th.html" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">「Webは一年くらい開発を止めておこう」という発言がありました</a>。</p>

<p><b class="speaker saito">斉藤</b> 僕もppkの発言は読みました。普通、僕らの開発でも、2年も経てばたくさん技術的負債が溜まっていってしまうものなのに、<strong>Webは壊れたままでどんどん新しい機能を追加していこうとしている</strong>。「一旦止まってしまうと死んでしまう」「止まることは後退することだ」というある種の強迫観念のようなものがあるのかもしれません。</p>

<p><b class="speaker asai">浅井</b> 実際には（Webの進化は）長い間止まってましたけどね(笑)。</p>

<p><b class="speaker shiraishi">白石</b> (HTML)4と5の間ね。</p>

<p><b class="speaker saito">斉藤</b> あの（進化が止まっていた）悲しさを繰り返しちゃダメだと、みんな思っているんじゃないでしょうか。僕は、Webはなくなってほしくないと思っているので、Web技術の進化は続いてほしいと考えています。ただ白石さんが仰るとおり、モバイルはネイティブでいいじゃん、という流れもあるのは確かです。</p>

<p><b class="speaker shiraishi">白石</b> 僕自身も、モバイルアプリであってもCordovaを使って開発していたりするので、Web技術は進化し続けてほしいと考えてはいます。CordovaやFirefox OSと言ったプラットフォームが今よりもっと力を持てば、先ほど僕が言った問題提起は不要だと思うんですけどね。</p>

<p><b class="speaker asai">浅井</b> 今はiOSやAndroidのシェアが非常に大きいですからね。そこら辺の状況が変わってくれば、Web技術の立ち位置ももう少し変わってくるんでしょうけどね。</p>

<p>また、先ほどあれだけ開発者に「声が欲しいんです」と訴えましたが、一方で仕様を作っているメンバーが念頭に置いているのは、<strong>5年10年先まで互換性を保ち、しかもあらゆるプラットフォームで動作する</strong>ことです。最初からこれを念頭に置いたプラットフォームは、人類にとって唯一のものだと思う。だから、5年10年先を見据えて絶え間なく技術を進化させていくというのは、誰かがやらなくてはならないと思っています。</p>

<p><b class="speaker shiraishi">白石</b> そう考えると、<strong>昔の「ユースケースありき」で仕様を決めていくというのは少し無理があったのかな、と思えます</strong>ね。5年10年経ったら、ユースケースなんて同じなわけがないですし。そう考えても、Extensible Webというのは正しい方向なんじゃないかと思えてきました。</p>

<p><b class="speaker daniel">ダニエル</b> そうですね。HTML5の世界は、長らくユースケースベースでした。例えばHTML5に何かを提案しようとすると、Ian Hickson（※）の答えは決まって「あなたのユースケースを教えて下さい」（「What&#8217;s your use case?」）でしたし。Extensible Webは、そうしたパラダイムからの脱却という面は少なからずあると思います。
<small>
※ ppk…Peter-Paul Koch氏のこと。著名なWebエンジニアで、<a href="http://www.quirksmode.org/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">QuirksMode</a>というサイトを運営している。</p>

<p>※ Ian Hickson…HTML5を始め、近年の様々なAPI仕様を策定するにあたって中心的な役割を果たしていた人物。相性はHixie。
</small></p>

<p><img src="/wp-content/uploads/2015/08/DSC_0090.png" alt="" width="640" height="403" class="aligncenter size-full wp-image-16720" srcset="/wp-content/uploads/2015/08/DSC_0090.png 640w, /wp-content/uploads/2015/08/DSC_0090-300x189.png 300w, /wp-content/uploads/2015/08/DSC_0090-207x130.png 207w" sizes="(max-width: 640px) 100vw, 640px" /></p>

<h2>新たなライブラリ、仕様書の変化 &#8211; Extensible Webがもたらしつつある変化とは</h2>

<p><b class="speaker daniel">ダニエル</b> CSSの方でも、ユースケースありきの考え方から脱却しつつあります。例えば<strong>「<a href="https://github.com/w3c/css-houdini-drafts" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">CSS Houdini</a>」は、ユースケースを考えずにCSSの基盤を公開して、その上に新たな機能を載せていく</strong>というアイデアです。</p>

<p>例えば、「新しいセレクタが欲しい」という場合、CSSの低レベルAPIで独自のCSSセレクタを作ったり…ということが想定されています。</p>

<p><b class="speaker komatsu">小松</b> 正確ではありませんが、「Web ComponentsのCSS版」といえばわかりやすいんじゃないかな。</p>

<p><b class="speaker saito">斉藤</b> 「独自のCSSセレクタを作る」というのを実現する<a href="http://www.hitchjs.com/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">hitch.js</a>というライブラリはすでにありますね。</p>

<p><b class="speaker shiraishi">白石</b> （READMEの例を一見して）自分の好きなセレクタを書ける！これはすごい。いやー、未来的な話になってきましたね。</p>

<p><b class="speaker saito">斉藤</b> CSSにまつわる話で言うと、<a href="https://github.com/marcj/css-element-queries" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">CSS Element Query</a>っていうのもありますね。</p>

<p><b class="speaker shiraishi">白石</b> （こちらもREADMEの例を一見して）ああ、これは使いやすそうですね。メディアクエリで「巨大なif」みたいな感じになるのが防げますね(笑)。</p>

<p><b class="speaker komatsu">小松</b> ほんとだ、これは便利そう。</p>

<p><b class="speaker daniel">ダニエル</b>
ちょっといいですか？<strong>今ここで起きていることこそが、Extensible Webが目指す形だと思いました</strong>。</p>

<p>これまでは、まず英語でできた仕様書しかなくて、その後コードやデモが整備されるまでは中々APIを理解できない。英語がよく読めない人たちにとってはなおさらです。</p>

<p><strong>でも今ここで起きていたのは、アイデアがコードで示されていて、皆さんは説明よりも先にコードを読んでいました。そして、「これはいい」とか「これは良くない」とかそういう話で盛り上がっていた</strong>。</p>

<p><b class="speaker komatsu">小松</b> 確かに。それに、仕様書にコードスニペットが記載されるという動きも、どんどん広がってますよね。そっちのほうがずっと分かりやすいから。</p>

<p><b class="speaker shiraishi">白石</b> そうですよねー、<strong>WebIDL</strong>（※）で示されたインターフェース定義から、どう動くのか想像するのとかって、割としんどかったですからね。そもそもWebIDLの読み方を勉強しなくちゃならない。</p>

<p><b class="speaker saito">斉藤</b> 「仕様書の読み方」みたいな講座があってもいいかもしれませんよね(笑)。</p>

<p><small>
※ WebIDL…W3Cのドキュメントで使用される、Web技術用のインターフェース定義言語（IDL:Interface Definition Language）
</small></p>

<h2>Extensible Webから探る、Webの未来</h2>

<p><b class="speaker shiraishi">白石</b> では、最後のトピックとして、Webブラウザの未来を探ってみたいと思うのですが、いかがでしょう？例えば以前、「Webは死ぬか」という対談を行った時に、Googleの及川さんが、「ブラウザコードもコンポーネント化が進んで、必要に応じてコンポーネントがダウンロードされる」という可能性を示唆してくれたのですが。</p>

<p><b class="speaker komatsu">小松</b> 例えばLinuxディストリビューションを想定してみるのもいいかもしれませんね。Linuxのカーネルに当たるのが現在のブラウザエンジン（のコア部分）で、その他の部分、例えばJavaScriptライブラリや利用頻度がそこまで高くないAPIとかは、パッケージみたいな扱いになるとか。</p>

<p><b class="speaker daniel">ダニエル</b> 未来のブラウザという話で言うと、<strong>もっと専門的なブラウザが出てくる可能性もある</strong>のかな、と考えています。例えば<a href="http://www.espial.com/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">Espial</a>という会社がありまして、別にここは新しい会社ではありませんが、TV専用のブラウザを作っていて、結構使われています。
こういうブラウザが、TVに関係する機能だけ実装すればいいのと同じように、家電専用のブラウザとか、色んな用途に特化したブラウザが出てくる可能性は大きいと思います。</p>

<p><b class="speaker asai">浅井</b> ブラウザが様々なデバイスで使われるようになっていくと、そのうちブラウザというのはユーザから見えなくなって、意識されなくなっていく。四角くなくなるとか、UIのないブラウザとかが普通に使われるようになっていく。</p>

<p><b class="speaker saito">斉藤</b> ブラウザがどこにでもある、って世界ですね。</p>

<p><b class="speaker shiraishi">白石</b> ただ例えば、ウェアラブルデバイスにブラウザが乗るのは当面ないような気もしますね。パフォーマンスの問題もありますし。</p>

<p><b class="speaker saito">斉藤</b> それは確かにそうかもしれません。が、何をもってブラウザと呼ぶのか、という話もありますね。例えば最近読んだのは、車通勤している最中に、Mediumの記事を読み上げてほしいという話があって。そのためのAPIを作ってはという話だったのですが、サーバ側でMediumのHTMLを解釈して、音声データだけをダウンロードしてクライアントで再生するようにすれば、HTMLを解釈する「ブラウザ」はクライアント側になくてもいいわけです。このように、Webページを「聞く」という行為、それすらも「ブラウジング」と言えると思います。</p>

<p><b class="speaker shiraishi">白石</b> なるほど、<strong>「ブラウザがどこにでもある」という世界を考えると、逆にブラウザが手元になくてもいい</strong>わけですね。HTMLが単なる音声データのためのデータソースになっている。</p>

<p><b class="speaker asai">浅井</b> そういうサービスを作るにあたっても、Web技術を使うようにすると、特許の問題とかが起きにくいんです。</p>

<p><b class="speaker saito">斉藤</b> ああ、それはありますね。</p>

<p><b class="speaker asai">浅井</b> …新しいものを作るときに、エコシステムが広がるのをブロックしてしまう原因を、Webは比較的解決していたり、最初から意識していたりすることが多いので、Web技術が広がってくれると、</p>

<p><b class="speaker shiraishi">白石</b> 広がってくれると？</p>

<p><b class="speaker asai">浅井</b> <strong>より人類は幸せになれます</strong>。</p>

<p><b class="speaker shiraishi">白石</b> 話でかい(笑)。〆の言葉としていい感じのフレーズが出たところで、本対談を終わりにしたいと思います。皆様、本日はどうもありがとうございました！</p>
]]></content:encoded>
			</item>
		<item>
		<title>Web ComponentsのこれからーPolymer 0.8、X-Tag、Brick、Bosonic</title>
		<link>/1000ch/14400/</link>
		<pubDate>Thu, 07 May 2015 00:00:38 +0000</pubDate>
		<dc:creator><![CDATA[泉水翔吾]]></dc:creator>
				<category><![CDATA[最新動向]]></category>
		<category><![CDATA[Polymer]]></category>
		<category><![CDATA[Web Components]]></category>

		<guid isPermaLink="false">/?p=14400</guid>
		<description><![CDATA[連載： 基礎からわかる Web Components 徹底解説 〜仕様から実装まで理解する〜 (5)この記事は、連載「基礎からわかるWeb Components徹底解説～仕様から実装まで理解する〜」の第5回目になります。...]]></description>
				<content:encoded><![CDATA[<div class="seriesmeta">連載： <a href="https://html5experts.jp/series/web-components-2/" class="series-214" title="基礎からわかる Web Components 徹底解説 〜仕様から実装まで理解する〜" data-wpel-link="internal">基礎からわかる Web Components 徹底解説 〜仕様から実装まで理解する〜</a> (5)</div><p>この記事は、連載「基礎からわかるWeb Components徹底解説～仕様から実装まで理解する〜」の第5回目になります。今回は、先日発表されたPolymer 0.8の変更点、MozillaのWeb Componentsへの関わり方やX-Tag、Brick、BosonicといったPolymer以外の周辺ライブラリについて紹介します。</p>

<h2>Polymer 0.8のリリース</h2>

<p>先日、Polymerのバージョン0.8がリリースされました。</p>

<ul>
<li><a href="https://blog.polymer-project.org/updates/2015/03/27/why-0.8/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">0.8 Released! &#8211; Polymer Blog</a></li>
</ul>

<p>0.8は1.0のリリースに向けたアルファリリースと位置付けられています。APIも正式版への提案として大きく変更が加えられており、これまでとの互換性も保たれていません。既に実践でPolymerを使っていて、0.8へアップデートを行う場合はこれまでのコンポーネントを作り直す必要があります。</p>

<p>アルファ版ということで、ユーザーのフィードバックや再設計を経て、さらなる変更がある可能性もありますが、より完成度の高いライブラリに近づいていくことでしょう。アップデートに伴い、どのような変更があるのかを見ていきます。</p>

<h3>ポリフィルライブラリ</h3>

<p>これまでポリフィルライブラリとして推奨されてきた<code>webcomponents.js</code>ですが、以降は<code>webcomponents-lite.js</code>が推奨されています。<code>webcomponents.js</code>と<code>webcomponents-lite.js</code>の差はShadow DOMのポリフィルを含んでいるかどうかなのですが、Polymer 0.8ではよりシンプルで軽量な <strong>shady DOM</strong> というShadow DOMのポリフィルを含んでいるためです。</p>

<ul>
<li><a href="https://github.com/webcomponents/webcomponentsjs" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">webcomponents/webcomponentsjs</a></li>
<li><a href="https://github.com/webcomponents/webcomponents-lite" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">webcomponents/webcomponents-lite</a></li>
</ul>

<p>異なる用途でShadow DOMのポリフィルを必要とする場合は別ですが、Polymerを利用するためであれば、<code>webcomponents.js</code>の重いShadow DOMのポリフィルを含まず、軽量な<code>webcomponents-lite.js</code>を選択するのが望ましいと言えます。</p>

<h3>軽量化とパフォーマンスの向上</h3>

<p>APIの大きな見直し（後述）と抜本的なリファクタリングによって、ライブラリのファイルサイズの軽量化と実行パフォーマンスの向上が図られています。以下は<a href="http://polymerlabs.github.io/benchmarks/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">PolymerLabs/benchmarks</a>で試すことができるベンチマークの結果です（Polymer公式サイトより引用）。初期描画までの時間の棒グラフになっており、低ければ低いほど描画までの時間が短くパフォーマンスが良いということになります。</p>

<p><img src="/wp-content/uploads/2015/04/benchmark-640x480.png" alt="benchmark" width="640" height="480" class="alignnone size-large wp-image-14436" srcset="/wp-content/uploads/2015/04/benchmark.png 640w, /wp-content/uploads/2015/04/benchmark-300x225.png 300w, /wp-content/uploads/2015/04/benchmark-207x155.png 207w" sizes="(max-width: 640px) 100vw, 640px" /></p>

<p>いくつかのデバイス・ブラウザで計測されていますが、いずれも0.5に比べて0.8が数倍高速に動作するという結果が出ています。もとよりWeb ComponentsはHTML ImportsのCustom Elementsの遅延評価されるという性質によるコンポーネントのがたつきやチラつきが問題になりがちですが、最も重要である初期描画までのパフォーマンスが向上されているのは嬉しいところです。</p>

<h2>互換性のない大きなAPIの変更</h2>

<p>冒頭で述べた通り、0.5以前と互換性はありません。</p>

<ul>
<li><a href="https://www.polymer-project.org/0.8/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">About this release &#8211; Polymer</a></li>
<li><a href="https://www.polymer-project.org/0.8/docs/migration.html" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">Migration guide &#8211; Polymer</a></li>
</ul>

<p>リリースノートとマイグレーションガイドを元に主な変更点を見ていきます。さらなる詳細な差分については、公式ドキュメントを確認してください。</p>

<h3>カスタム要素の登録</h3>

<p>これまでは、&lt;polymer-element&gt;要素を用いてカスタム要素の登録を行ってきました。</p>

<p></p><pre class="crayon-plain-tag">&lt;polymer-element name="my-element"&gt;
  &lt;template&gt;
    &lt;style&gt;
      div { color: red; }
    &lt;/style&gt;
    &lt;div&gt;Shadow DOM in My Element&lt;/div&gt;
  &lt;/template&gt;
  &lt;script&gt;
    Polymer();
  &lt;/script&gt;
&lt;/polymer-element&gt;</pre><p></p>

<p>0.8からは以下のように、&lt;dom-module&gt;を起点にした方法に変更されます。&lt;dom-module&gt;要素のIDに登録したいカスタム要素名（ここでは<code>my-element</code>）を指定し、<code>Polymer</code>コンストラクタでそのIDを参照しています。</p>

<p></p><pre class="crayon-plain-tag">&lt;dom-module id="my-element"&gt;
  &lt;style&gt;
    div { color: red; }
  &lt;/style&gt;
  &lt;template&gt;
    &lt;div&gt;Shadow DOM in My Element&lt;/div&gt;
  &lt;/template&gt;
&lt;/dom-module&gt;

&lt;script&gt;
  var MyElement = Polymer({is: 'my-element'});
&lt;/script&gt;</pre><p></p>

<p><code>Polymer({is: 'my-element'});</code>の実行より前に、&lt;dom-module&gt;がロードされている必要があります。&lt;style&gt;タグを&lt;template&gt;の外に配置するようになった点にも注意して下さい。要素の継承についても同様に<code>extends</code>キーワードで行うことができますが、0.5以前では可能であったカスタム要素の継承は廃止され、&lt;button&gt;や&lt;textarea&gt;のようなビルドインのHTML要素のみになっています。また、これまでは<code>constructor</code>属性にコンストラクタ関数名を指定していましたが、0.8では属性が廃止されるとともに<code>Polymer()</code>がカスタム要素のコンストラクタを返却するようになりました。</p>

<p><code>document.registerElement</code>の第二引数に指定する<code>extends</code>の値にもカスタム要素名を指定することはできず、コンストラクタ関数の返却も<code>document.registerElement</code>が行います。いずれも素の挙動に近い振る舞いになったと言えるでしょう。</p>

<h3>カスタム要素のパースの順序</h3>

<p>カスタム要素を含むカスタム要素を作成する場合は、内包するカスタム要素が事前に登録されている必要があります。つまり、&lt;child-element&gt;を含む&lt;parent-element&gt;を作成する場合、&lt;child-element&gt;が事前に登録されていなければなりません。</p>

<h3>デフォルト属性とプロパティの宣言</h3>

<p>カスタム要素のデフォルト属性とプロパティ宣言の方法も変わります。0.5までは以下のように、デフォルト属性は&lt;polymer-element&gt;に、プロパティの宣言は<code>attributes</code>にスペース区切りで指定していました。</p>

<p></p><pre class="crayon-plain-tag">&lt;polymer-element name="your-element" attributes="foo bar" role="button" layout horizontal wrap&gt;
  &lt;template&gt;
    &lt;button&gt;Your Element&lt;/button&gt;
  &lt;/template&gt;
  &lt;script&gt;
    Polymer({
      foo: 0,
      bar: 'Hello!'
    });
  &lt;/script&gt;
&lt;/polymer-element&gt;</pre><p></p>

<p>0.8以降は以下のように、<code>Polymer()</code>コンストラクタに<code>hostAttributes</code>や<code>properties</code>を渡すことで宣言します。</p>

<p></p><pre class="crayon-plain-tag">&lt;dom-module id="your-element"&gt;
  &lt;template&gt;
    &lt;button&gt;Your Element&lt;/button&gt;
  &lt;/template&gt;
&lt;/dom-module&gt;

&lt;script&gt;
  Polymer({
    is: 'your-element',
    hostAttributes: {
      role: 'button',
      class: 'layout horizontal wrap'
    },
    properties: {
      foo: {
        type: Number,
        value: 0
      },
      bar: {
        type: String,
        value: 'Hello!'
      }
    }
  });
&lt;/script&gt;</pre><p></p>

<p><code>layout</code>、<code>horizontal</code>、<code>wrap</code>といったようなレイアウトに関するカスタム属性も通常のCSSクラスになり、<code>hostAttributes</code>の<code>class</code>に指定します。また、このレイアウト機能はPolymerのコアから分離され<code>polymer.html</code>に同梱されなくなったので、別途<code>layout.html</code>をインポートする必要があります。</p>

<h3>オブザーバーの登録</h3>

<p>プロパティの値の監視や、宣言的なイベントハンドラ登録といった機能もPolymerの強力な機能のひとつですが、これらにも少々変更があります。</p>

<p>これまでは、<code>foo</code>というプロパティに対して<code>fooChanged</code>というオブザーバー関数を宣言すると命名規則によって自動でバインドされる機能がありました。また、IDを振った要素は<code>this.$.id</code>という形でコンストラクタ内でノードを参照することが可能であり、それを<code>observers</code>に定義することでもプロパティの監視が可能でした。</p>

<p></p><pre class="crayon-plain-tag">&lt;polymer-element name="your-element" attributes="foo"&gt;
  &lt;template&gt;
    &lt;input type="text" id="input"&gt;
  &lt;/template&gt;
  &lt;script&gt;
    Polymer({
      foo: 0,
      observers: {
        'this.&amp;.input.value': 'inputValueChanged'
      },
      fooChanged: function (oldValue, newValue) {
        console.log('newValue is ', newValue);
      },
      inputValueChanged: function () {
        console.log('this.&amp;.input.value is changed');
      }
    });
  &lt;/script&gt;
&lt;/polymer-element&gt;</pre><p></p>

<p>0.8からはこの<code>propertyName</code>に対して<code>propertyNameChanged</code>という関数を定義することで自動バインドされる仕組みと、IDを振った要素が<code>this.$</code>にぶら下がる機能が廃止されます。これによってプロパティの監視を行うには、以下のように、ブラケットで囲った変数に対し、<code>observer</code>属性にオブザーバー関数を明示的に宣言することになります。</p>

<p></p><pre class="crayon-plain-tag">&lt;dom-module id="your-element"&gt;
  &lt;template&gt;
    &lt;input type="text" value="{{inputValue}}"&gt;
  &lt;/template&gt;
&lt;/dom-module&gt;

&lt;script&gt;
  Polymer({
    is: 'your-element',
    properties: {
      foo: {
        type: Number,
        value: 0,
        observer: 'fooChanged'
      },
      inputValue: {
        observer: 'inputValueChanged'
      }
    },
    fooChanged: function (oldValue, newValue) {
      console.log('newValue is ', newValue);
    },
    inputValueChanged: function () {
      console.log('inputValue is changed');
    }
  });
&lt;/script&gt;</pre><p></p>

<p>暗黙的にオブザーバー関数がバインドされる分、直感的に解り難い機能であったので、このように明示的な宣言方法になるのは嬉しいところです。</p>

<h3>イベントハンドラの登録とデータバインディング</h3>

<p>ブラケット<code>{{}}</code>によるデータバインディングや、イベントハンドラの登録もPolymerお馴染みの機能ですが、これらにも少々変更があります。</p>

<p></p><pre class="crayon-plain-tag">&lt;polymer-element name="our-element"&gt;
  &lt;template&gt;
    &lt;input type="text" value="{{firstName}}"&gt;
    &lt;input type="text" value="{{lastName}}"&gt;
    &lt;button on-click="{{onClick}}"&gt;Say full name&lt;/button&gt;
  &lt;/template&gt;
  &lt;script&gt;
    Polymer({
      onClick: function () {
        alert("{{firstName + ' ' + lastName}}");
      }
    });
  &lt;/script&gt;
&lt;/polymer-element&gt;</pre><p></p>

<p>0.8からは<code>{{}}</code>内の式の評価はサポートされなくなります。</p>

<p>この例で言えば、<code>"{{firstName + ' ' + lastName}}"</code>のような表現はできなくなります。代わりに<code>computed</code>を用いて、式評価後の値を参照するプロパティを宣言する必要があります。これは0.5以前とは異なり、0.8からは<code>properties</code>の配下に定義する属性になることに注意してください。</p>

<p>同じく、<code>{{}}</code>を使って<code>on-click="{{onClick}}"</code>のように定義していたイベントハンドラの登録は、カーリーブラケットを使わずに記述します。</p>

<p></p><pre class="crayon-plain-tag">&lt;dom-module id="our-element"&gt;
  &lt;template&gt;
    &lt;input type="text" value="{{firstName}}"&gt;
    &lt;input type="text" value="{{lastName}}"&gt;
    &lt;button on-click="onClick"&gt;Say full name&lt;/button&gt;
  &lt;/template&gt;
&lt;/dom-module&gt;

&lt;script&gt;
  Polymer({
    is: 'our-element',
    properties: {
      firstName: String,
      lastName: String,
      fullName: {
        type: String,
        computed: 'computeFullName(firstName, lastName)'
      }
    },
    computeFullName: function (firstName, lastName) {
      return firstName + ' ' + lastName;
    },
    onClick: function () {
      alert('{{fullName}}');
    }
  });
&lt;/script&gt;</pre><p></p>

<p>このように<code>fullName</code>に<code>computed: computeFullName(firstName, lastName)</code>とすることで<code>computeFullName</code>の実行結果を参照することが可能です。</p>

<h3>DOMの操作</h3>

<p>Polymer内でDOM操作を行う場合、通常のShadow Rootから実行するDOMのAPIではなく、<code>Polymer.dom</code>という専用のAPIを使う必要があります。</p>

<ul>
<li><code>Polymer.dom(parent).appendChild(node)</code></li>
<li><code>Polymer.dom(parent).insertBefore(node, beforeNode)</code></li>
<li><code>Polymer.dom(parent).removeChild(node)</code></li>
<li><code>Polymer.dom(parent).querySelector(selector)</code></li>
<li><code>Polymer.dom(parent).querySelectorAll(selector)</code></li>
<li><code>Polymer.dom(parent).childNodes</code></li>
<li><code>Polymer.dom(node).parentNode</code></li>
<li><code>Polymer.dom(contentElement).getDistributedNodes()</code></li>
<li><code>Polymer.dom(node).getDestinationInsertionPoints()</code></li>
</ul>

<p><code>Polymer.dom</code>から行う追加や削除といったDOM操作は、パフォーマンスを考慮し遅延して実行するようになっています。そのため、操作後のノードの座標や<code>getComputedStyle()</code>を使ったスタイルの取得をする場合は、操作を<code>Polymer.dom.flush()</code>を使って適時実行し、反映します。</p>

<p></p><pre class="crayon-plain-tag">// 従来のDOM操作
this.appendChild(node);
this.shadowRoot.appendChild(node);

// Polymer.domを使ったDOM操作
Polymer.dom(this).appendChild(node);
Polymer.dom(this.root).appendChild(node);</pre><p></p>

<p>いずれもDOMのAPIと同じ命名と引数で設計されていますが、サブセットとして用意されているに過ぎず、完全に互換性があるわけではありません。例えば、<code>firstChild</code>といったプロパティは用意されていないので、この場合は代わりに<code>childNodes[0]</code>を使ってください。</p>

<h2>MozillaのWeb Componentsへの関わり方</h2>

<p>MozillaもWeb Componentsに対し、積極的な姿勢を見せています。FirefoxでもWeb Componentsの仕様のうち、いくつかが実験的に実装され、またX-TagやBrickといったWeb Componentsをつかったコンポーネント作成を後押しするライブラリもリリースしています。</p>

<h3>X-Tag</h3>

<p><a href="https://github.com/x-tag" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">X-Tag</a>はWeb Componentsの作成をサポートするライブラリです。<code>webcomponents.js</code>をポリフィルとし、記述の簡略化や一元化いったライブラリとしての目的もPolymerと似ている部分がありますが、Polymerに比べて多くのブラウザをサポートしているという特徴があります。X-Tagのブラウザターゲットは以下の通りです。</p>

<ul>
<li>Firefox 5+ desktop &amp; mobile</li>
<li>Chrome 4+, Android 2.1+</li>
<li>Safari 4+ desktop &amp; mobile</li>
<li>Internet Explorer 9+</li>
<li>Opera 11+ desktop &amp; mobile</li>
</ul>

<p>以下は公式ドキュメント引用のX-Tagを使ったカスタム要素作成のコード例です。Polymerほど多機能ではない分、シンプルで全体像を把握しやすいかもしれません。</p>

<p></p><pre class="crayon-plain-tag">xtag.register('x-accordion', {
  // extend existing elements
  extends: 'div',
  lifecycle:{
    created: function(){
      // fired once at the time a component
      // is initially created or parsed
    },
    inserted: function(){
      // fired each time a component
      // is inserted into the DOM
    },
    removed: function(){
      // fired each time an element
      // is removed from DOM
    },
    attributeChanged: function(){
      // fired when attributes are set
    }
  },
  events: {
    'click:delegate(x-toggler)': function(){
      // activate a clicked toggler
    }
  },
  accessors: {
    'togglers': {
      get: function(){
        // return all toggler children
      },
      set: function(value){
        // set the toggler children
      }
    }
  },
  methods: {
    nextToggler: function(){
      // activate the next toggler
    },
    previousToggler: function(){
      // activate the previous toggler
    }
  }
});</pre><p></p>

<h3>Brick</h3>

<p>X-Tagだけでなく、UIコンポーネント群として配布しているのが<a href="http://mozbrick.github.io/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">Brick</a>です。PolymerとX-Tagとの関係になぞらえるなら、BrickはCore ElementsやPaper Elementsと同じような存在と言えます。以前まではX-Tagが使われていましたが、現在は非依存になっています。</p>

<p>BrickもPolymerの対抗馬として注目されていましたが、開発が中断されているのか、最近は更新がない状態です。参照しているポリフィルライブラリも<code>webcomponents.js</code>ではなく、旧称の<code>platform.js</code>になっているので、利用する場合は注意してください。</p>

<h3>Web Componentsの各仕様へのMozillaの対応</h3>

<p>2014年12月の記事ですが、MozillaのWeb Componentsに対する興味深い記事が公開されました。</p>

<ul>
<li><a href="https://hacks.mozilla.org/2014/12/mozilla-and-web-components/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">Mozilla and Web Components: Update</a></li>
</ul>

<p>記事には、端的に述べると <strong>「Custom ElementsとShadow DOMの実装は進め、HTML Importsの実装は見送ります。差し当たって、HTML Importsの機能はJavaScriptのライブラリでやってください。」</strong> とあります。HTML Importsが実装されないことについての議論がコメント欄にて行われていますが、この記事の筆者である<a href="https://annevankesteren.nl/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">Anne van Kesteren</a>は以下のように述べています。</p>

<p>&gt; Both ES6 modules and service workers open up resource dependency management to web developers. And while ES6 modules is mostly intended for JavaScript, we want to see what kind of dependency systems will be built on these two systems in libraries and frameworks before committing to a standardized design. Especially before committing to one that is not influenced by them. <strong>（ES6 modulesやService Workersも依存関係の解決に関わってくる。ES6 modulesはJavaScript向けのものだし、ライブラリやフレームワークにとってどのような機構になるかを見たい）</strong></p>

<p>依存管理の仕組みが、HTML ImportsとES6 modules、Service Workerのような、Web WorkersのimportScriptsといった方法が複数存在してしまうことを懸念してのことと察します。例えばHTML ImportsとES6 modulesは目的を共有するものではないはずですが、HTML ImportsでロードするHTML内でES6 modulesが使われるようなケースも加味して、様子を見たいということでしょう。</p>

<h2>Bosonic</h2>

<p>BosonicもPolymerやX-Tag同様に、Web Componentsの作成を支援するライブラリです。</p>

<ul>
<li><a href="http://bosonic.github.io/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">Bosonic Web Component</a></li>
<li><a href="https://github.com/bosonic/bosonic" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">bosonic/bosonic &#8211; GitHub</a></li>
</ul>

<p>PolymerやX-Tagと異なるのは、これらのようにライブラリとして機能を補完したりするのではなく、作成したWeb ComponentsをBosonicを使って事前にビルドするトランスパイラであるという点です。Bosonicでビルドすることで、Internet ExplorerやSafariを含めたWeb Componentsに関するAPIが実装されていないブラウザでも機能するコードが生成されます。</p>

<p>Bosonicはブラウザターゲットは以下の通りです。</p>

<ul>
<li>Internet Explorer 9, 10, 11</li>
<li>Safari 8</li>
<li>Android 4.4</li>
<li>iOS 8.1</li>
<li>Chrome 35</li>
<li>Firefox 30</li>
</ul>

<h3>Bosonicで生成するコード例</h3>

<p>以下は公式で例示されている&lt;b-hello-world&gt;というWeb ComponentsをBosonicを使ってビルドする例です。</p>

<p></p><pre class="crayon-plain-tag">&lt;element name="b-hello-world"&gt;
  &lt;style&gt;
    :host {
      text-align: center;
      font-weight: bold;
      color: red;
    }
  &lt;/style&gt;
  &lt;template&gt;
    &lt;p&gt;Hello world!&lt;/p&gt;
  &lt;/template&gt;
  &lt;script&gt;
    ({
      createdCallback: function() {
        var root = this.createShadowRoot();
        root.appendChild(this.template.content.cloneNode(true));
      }
    });
  &lt;/script&gt;
&lt;/element&gt;</pre><p></p>

<p>Bosonicを使ってコンパイルすると、以下の様なCSSとJavaScriptのコードが出力されます。</p>

<p></p><pre class="crayon-plain-tag">b-hello-world {
  text-align: center;
  font-weight: bold;
  color: red;
}</pre><p></p>

<p></p><pre class="crayon-plain-tag">(function () {
  var BHelloWorldPrototype = Object.create(HTMLElement.prototype, {
    createdCallback: {
      enumerable: true,
      value: function () {
        var root = this.createShadowRoot();
        root.appendChild(this.template.content.cloneNode(true));
      }
    }
  });
  window.BHelloWorld = document.registerElement('b-hello-world', { prototype: BHelloWorldPrototype });
  Object.defineProperty(BHelloWorld.prototype, '_super', {
    enumerable: false,
    writable: false,
    configurable: false,
    value: HTMLElement.prototype
  });
  Object.defineProperty(BHelloWorldPrototype, 'template', {
    get: function () {
      var fragment = document.createDocumentFragment();
      var div = fragment.appendChild(document.createElement('div'));
      div.innerHTML = ' &lt;p&gt;Hello world!&lt;/p&gt; ';
      while (child = div.firstChild) {
        fragment.insertBefore(child, div);
      }
      fragment.removeChild(div);
      return { content: fragment };
    }
  });
}());</pre><p></p>

<p>これらのファイルと、いくつかのポリフィル（HTMLImports、MutationObservers、WeakMap、Custom Elements）をHTMLでロードすることで、非対応のブラウザでも&lt;b-hello-world&gt;を使うことができます。</p>

<h3>トランスパイラとして導入するメリット</h3>

<p>新しいAPIで書かれたコードを、非対応のブラウザ向けに従来のAPIで実行できるようにするというのは、ES6を<a href="https://babeljs.io/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">Babel</a>でES5に変換するというアプローチと同様です。新しい技術の導入は常にブラウザサポートと天秤にかかり、サポートを優先するが故に新しい技術を試すことができないというジレンマも多いでしょう。しかし、こういったトランスパイラによって、新しい技術の導入と古いブラウザのサポートが、コストをかけずに両立できるのは非常に嬉しいところなのではないでしょうか。</p>

<p>&lt;element&gt;タグを使った古い記述であったり、リポジトリの更新もしばらくされていないなど、使うには少々抵抗があります。しかし、トランスパイラというアプローチは非常に興味深いものがありますので、メンテナンスが再開されるのを期待したいところです。</p>

<h2>まとめ</h2>

<p>Polymer 0.8のアップデート、X-Tag・Brick・Bosonic、およびFirefoxの実装状況について紹介しました。</p>

<p>ブラウザの実装状況は、Internet Explorer・Safariが未だに思わしくありません。仕様についても、FirefoxがHTML Importsの実装を遅らせたようにまだ確実とはいえない状況です。しかしこれは議論が行われている表れでもあり、Polymerの0.8がリリースされたことも含めて、Web Componentsに関する技術は普及に向けて着実に前進しているといえます。</p>

<p>しかし、Shadow DOMによってCSSやJSがカプセル化されても、今度はコンポーネント化のアプローチについて頭を悩ませることになるでしょう。Web Componentsが一般化するには仕様の安定やブラウザのサポートだけではなく、我々開発者でナレッジを蓄積していくことが最も重要です。</p>
]]></content:encoded>
		
		<series:name><![CDATA[基礎からわかる Web Components 徹底解説 〜仕様から実装まで理解する〜]]></series:name>
	</item>
		<item>
		<title>昨今のCSS設計事情からみるCSS設計のあり方とは</title>
		<link>/hiloki/14372/</link>
		<pubDate>Wed, 15 Apr 2015 00:00:23 +0000</pubDate>
		<dc:creator><![CDATA[谷拓樹]]></dc:creator>
				<category><![CDATA[最新動向]]></category>
		<category><![CDATA[CSS]]></category>
		<category><![CDATA[Web Components]]></category>
		<category><![CDATA[マークアップ]]></category>

		<guid isPermaLink="false">/?p=14372</guid>
		<description><![CDATA[連載： HTML5 Conference 2015 特集 (4)本記事は2015年1月に開催されたHTML5 Conferenceでお話させていただいた、 「Beyond CSS Architecture」というCSS設...]]></description>
				<content:encoded><![CDATA[<div class="seriesmeta">連載： <a href="https://html5experts.jp/series/h5conf2015/" class="series-257" title="HTML5 Conference 2015 特集" data-wpel-link="internal">HTML5 Conference 2015 特集</a> (4)</div><p>本記事は2015年1月に開催された<a href="http://events.html5j.org/conference/2015/1/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">HTML5 Conference</a>でお話させていただいた、
「Beyond CSS Architecture」というCSS設計のセッションをフォローアップする記事です。</p>

<p>本記事では、このセッションの概要と補足、またセッション中に説明できなかった点などについて書いていきます。</p>

<p><img src="/wp-content/uploads/2015/04/beyondcssarchitecture.jpg" alt="" width="500" height="373" class="aligncenter size-full wp-image-14555" srcset="/wp-content/uploads/2015/04/beyondcssarchitecture.jpg 500w, /wp-content/uploads/2015/04/beyondcssarchitecture-300x224.jpg 300w, /wp-content/uploads/2015/04/beyondcssarchitecture-207x154.jpg 207w" sizes="(max-width: 500px) 100vw, 500px" /></p>

<p>※当日のセッションの動画・スライドも公開されているので、文末からご覧ください。</p>

<h2>CSSの難しさと、昨今のCSS設計事情</h2>

<p>この近年、CSSにおける設計論というのが話題に出てくるようになりました。筆者も拙著『<a href="http://www.amazon.co.jp/gp/product/4844336355" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">Web制作者のためのCSS設計の教科書</a>』を書いたり、各地でCSS設計をテーマとした講演をする機会が多くありました。</p>

<p>CSSの難しさというのは、<a href="https://html5experts.jp/t32k/13504/" data-wpel-link="internal">石本氏によるCSSコードの評価についての記事</a>にも書かれているのですが、CSSは良くも悪くも厳格なコード規約は少なく、ただ宣言的に書けばいいだけです。セレクタとその詳細度や、後出しされたルールの方が優先されるという、シンプルがゆえに「書く」のは簡単ですが、「直す」のは容易ではありません。</p>

<p>Normalize.cssの作者であり、現在Twitterのエンジニアであるニコラス・ギャラガー氏（<a href="https://twitter.com/necolas" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">@necolas</a>）のツイートを引用するならば、次のように考えられるかどうかです。</p>

<blockquote>
  <p>Replace &quot;can you build this?&quot; with &quot;can you maintain this without losing your minds?&quot;<br>
  &mdash; <a href="https://twitter.com/necolas/status/360170108028600320" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">Nicolas Gallagher (@necolas) </a></p>
</blockquote>

<p><br></p>

<p>複数人のチームでの開発はもちろんですが、自分のひとりの開発であったとしても、いざメンテナンスするとなったときに、数日前に自分が書いたCSSを呪うようなことはよくあります。</p>

<p>中長期的に運用されるWebサイト、Webサービスにおいては、その運用に耐えうるメンテナブルかつ、拡張性のあるCSSを書くことは非常に重要です。
こうしたCSS設計の話題が以前よりも見かけるようになったのは、単純な数ページのWebサイトよりも、少しリッチで複数のテンプレートが必要なWebサイト、Webサービスが増えてきていることもあり、メンテナブルなCSSにするための設計とは何か、というのが求められているからかもしれません。</p>

<h2>OOCSSとBEM</h2>

<p>セッション内でも取り上げている<a href="https://github.com/stubbornella/oocss/wiki" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">OOCSS</a>と<a href="https://en.bem.info/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">BEM</a>は、CSS設計を考える上で避けられない方法論のひとつです。</p>

<p>OOCSSは、ページ上で繰り返されるビジュアルパターンをオブジェクトと考え、そのオブジェクトはHTML/CSSまたはJavaScriptのコードの固まりで構成されます。それはボタンやリスト、見出しというような単位であったり、場合によってはただ文字色を赤くするためのものかもしれません。こうした作られた小さなオブジェクトをレゴのように組み合わせてUIを作るというのが、OOCSSの基本的なアプローチです。</p>

<p>BEMは、Yandexという会社のフロントエンド開発チームによって考えられた開発手法です。BEMはUIをBlock,Element,Modifierという分類で設計するのですが、BEMで使われている命名規則とその記法が特徴的で、Blockを名前空間として使うのが良いアイデアとされています。</p>

<p></p><pre class="crayon-plain-tag">.menu { ... } /* Block */
.menu__item { ... } /* Block + Element */
.user { ... } /* Block */
.user_login { ... } /* Block + Modifier */
.user__avatar { ... } /* Block + Element */
.user__name { ... } /* Block + Element */</pre><p></p>

<p>このコード例では<code>.menu</code>がBlockの単位となり、またそれがセレクタの接頭辞にすることで、マークアップ上でつけられたクラス名を見るだけで、どのUI（Block）に依存するものかが分かります。例えば<code>class="item"</code>だと抽象的すぎて何に依存しているかわかりませんが、<code>.menu__item</code>であれば分かる、ということです。</p>

<p>また<code>_</code>、<code>__</code>の記号の組み合わせは、設計上のルールとして、単語間がどういう関係性を持つのかを明確にしています。<code>__</code>は一見冗長で、普通に名前をつけるときには使わなそうですが、それが良い意味でただの命名ではなく、デリミタ（区切り）として使われているということです。</p>

<p>このBEMのアプローチの細かなルールは必ずしもオリジナルのBEMに倣っているものばかりではなく、<a href="http://csswizardry.com/2013/01/mindbemding-getting-your-head-round-bem-syntax/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">MindBEMding</a>のような独自のルールで運用されることもあります。筆者の<a href="https://github.com/hiloki/flocss" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">FLOCSS</a>も、いろいろなものを参考にして作成したものです。</p>

<h2>モダンなCSS設計の誤解</h2>

<p>OOCSS、BEMについて言及される記事を見ると、これらやCSS設計における大きな誤解を招いていると感じることがあります。</p>

<p>OOCSS派か、BEM派か、というような表現も見かけますが、多くの場合、OOCSSは複数のクラスを組み合わせるアプローチ、BEMは単一クラスのアプローチ、というような解釈をされているようです。</p>

<p>OOCSSが体系化された当時にはSassのようなメタ言語もなく、OOCSSを実現するためには複数のクラスを組み合わせるアプローチが適切だったというだけでしょう。事実、彼女自身が<a href="https://www.youtube.com/watch?v=GhX8iPcDSsI" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">&#8220;OOCSS and Preprocessors in a tree, K-I-S-S-I-N-G&#8221;</a>という講演で、OOCSSとSassを組み合わせたアプローチについて述べています。</p>

<p>また提唱者であるニコール・サリバン氏が関わったプロジェクトにおいては、<code>font-size</code>という単位でもオブジェクトとして分解することが、数百と宣言される<code>font-size</code>プロパティを、たった数個のクラスで管理することに意味がありました。</p>

<p>ただそのいくつかの例が拡大解釈され、<code>.red {color: red;}</code>や<code>.large {font-size: 36px}</code>というような、見た目だけの、コンテンツ派生の意味をもたないクラスを複数組み合わせるアプローチがOOCSSである、と考えられることは少なくありません。</p>

<p>しかし、OOCSSの本質は、現在のHTML/CSSでは難しいモジュラーなアプローチを実践するためのパラダイムである、と筆者は考えています。</p>

<p>一方、BEMについてもいくつかの誤解があるように感じています。Block、ElementあるいはModifierとしての命名と設計は、マークアップを見て、その構造をセレクタにするものではありません。</p>

<p></p><pre class="crayon-plain-tag">&lt;nav class="globalNav"&gt;
  &lt;ul&gt;
    &lt;li&gt;
      &lt;a href="/home"&gt;Home&lt;/a&gt;
    &lt;/li&gt;
    &lt;!-- more --&gt;
  &lt;/ul&gt;
&lt;/nav&gt;</pre><p></p>

<p>例えばこのようなマークアップがあった時に、その構造を意識してしまい、次のようなCSSにしてしまうことがあります。</p>

<p></p><pre class="crayon-plain-tag">&lt;nav class="globalNav"&gt;
  &lt;ul class="globalNav__menu"&gt;
    &lt;li class="globalNav__menu__item"&gt;
      &lt;a href="/home"&gt;Home&lt;/a&gt;
    &lt;/li&gt;
    &lt;!-- more --&gt;
  &lt;/ul&gt;
&lt;/nav&gt;</pre><p></p>

<p>極端な例ではありますが、近いコードを見ることはあるのではないでしょうか。こうなってしまうと、BEMが冗長すぎる、気持ちが悪い、というのは素直な感情だともいえます。</p>

<p>しかし本来のBEMらしい考え方であれば、このようなマークアップを元にセレクタに命名するものではなく、UIをBlock,Element,Modifierのツリー構造で考え、それが名前にも与えられるものです。</p>

<p>この例でいえば、<code>globalNav</code>をBlockとするならば、それを構成する要素は次のようになるかもしれません。</p>

<p></p><pre class="crayon-plain-tag">&lt;nav class="globalNav"&gt;
  &lt;ul class="globalNav__menu"&gt;
    &lt;li class="globalNav__menuItem"&gt;
      &lt;a href="/home"&gt;Home&lt;/a&gt;
    &lt;/li&gt;
    &lt;!-- more --&gt;
  &lt;/ul&gt;
&lt;/nav&gt;</pre><p></p>

<p>そもそも、もっと小さな単位にするべきかもしれません。</p>

<p></p><pre class="crayon-plain-tag">&lt;nav class="globalNav"&gt;
  &lt;ul class="globalNav__menu menu"&gt;
    &lt;li class="menu__item"&gt;
      &lt;a href="/home" class="menu__target"&gt;Home&lt;/a&gt;
    &lt;/li&gt;
    &lt;!-- more --&gt;
  &lt;/ul&gt;
&lt;/nav&gt;</pre><p></p>

<p>どちらが正しいかというものではなく、その時々で適切な命名や分割があるはずですが、少なくともマークアップの構造をなぞって親子関係を命名で表すのが、BEMの命名規則というわけではありません。</p>

<p>最後の例を見ての通り、BEMの記法であっても、複数のBlockとElement、つまりはそれぞれはOOCSS的にいえばオブジェクトであり、組み合わせによって作られるわけです。</p>

<p>つまり、OOCSS派かBEM派かという天秤があるわけではありませんし、思想として良いところを取り入れて、プロジェクトに適切な方法論、設計を考えることが重要です。</p>

<p>逆にいえば、これらは<a href="http://ja.wikipedia.org/wiki/%E9%8A%80%E3%81%AE%E5%BC%BE%E3%81%AA%E3%81%A9%E3%81%AA%E3%81%84" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">銀の弾丸</a>というわけでもありませんから、OOCSSやBEMがすべての問題を解決するわけでもありません。プロジェクトの規模やその運用の方向性によっては、もっと単純な規約のもとでCSSが書かれていても構いません。</p>

<p>いずれの場合も、そのプロジェクト内において一貫性が保たれていることのほうが大事で、<a href="https://github.com/necolas/idiomatic-css" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">Ideomatic CSS</a>から引用するならば、次のようなことです。</p>

<blockquote>
  <p>どんなに多くの人が貢献したとしても、どのコードも一人で書いたようにすること。<br>
  &mdash; <a href="https://github.com/necolas/idiomatic-css" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">Ideomatic CSS</a></p>
</blockquote>

<p>セッションで紹介しているツール、スタイルガイドや<a href="http://www.stylestats.org/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">StyleStats</a>のようなツールは、一貫性を保ったCSSを書くための補助となるものです。</p>

<p>これらもまたツールでしかなく、導入しただけで問題が解決するというわけではないので、どのように運用するか、自動化などを含めた仕組みを考えることがより重要です。</p>

<h2>まとめ</h2>

<p>セッションの最後に<a href="https://html5experts.jp/tag/web-components/" data-wpel-link="internal">Web Components</a>に触れていました。Shadow DOMによって、今のHTML/CSSにないスコープの概念がもたらされれば、現状HTML/CSSをモジュラーに設計・実装するためのいくつかの課題は解決するかもしれません。</p>

<p>しかし、それによってCSS設計が簡単になるか、といえば決してそうではありませんし、どちらかといえばより難しくなるかもしれません。</p>

<p>またWeb Componentsの実用は少し先かもしれませんが、現在でも<a href="https://html5experts.jp/hokaccha/13301/" data-wpel-link="internal">React</a>のようなものを採用したプロジェクトにおいては、CSSはどのように設計するか、というのは課題として出てきています。個人的にはそれを考えることは、HTML/CSSをより面白くするものでもあります。（その分の苦しみも多くありますが）</p>

<p>どのような未来がくるにせよ、よりよいCSS設計をするためには、より多くのパターンを知ることだと考えています。</p>

<p>同じリスト型のUIを組むにしても、どのようなパターンが目の前のプロジェクトにおいて適切か、それはパターンを多く知らなければいけません。</p>

<p>そのためには、世の中に多く公開されているフレームワーク、またはプロダクトとして公開されているWebサイトやWebサービスのコードを読むことが大事です。続々と出てくる、新たなOOCSSやBEMのような方法論たちも、食わず嫌いはせず一読してみてください。</p>

<p>CSS設計は非常に難しく、壊れないCSSを書くというのは不可能です。私は次の言葉を胸に、いつもCSSを書いています。</p>

<blockquote>
壊れない完璧な設計を求めるのではなく、壊れたときに勇気を持って修復できる設計を<br>
&mdash; <a href="https://html5experts.jp/cssradar/" data-wpel-link="internal">斉藤 祐也</a>
</blockquote>

<p><br></p>

<p>はじめから作ることはもちろん、どれだけシミュレーションや設計をしても壊れるときはありますから、それをいかに直しやすいものにするか、そしてそれが他の開発者にとって可能であり、数日後の自分でも直せるようなCSSを書くようにしましょう。</p>

<p>当日のセッションの動画・スライドは、こちらからご覧ください。</p>

<div class="aligncenter">

<!-- iframe plugin v.4.3 wordpress.org/plugins/iframe/ -->
<iframe width="560" height="315" src="https://www.youtube.com/embed/1VZ_Rm5_rY4" frameborder="0" 0="allowfullscreen" scrolling="yes" class="iframe-class"></iframe>

</div>

<p><a href="https://www.youtube.com/watch?v=1VZ_Rm5_rY4" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">Youtube</a> /
<a href="http://www.slideshare.net/hiloki/beyond-css-architecture" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">Slideshare</a></p>
]]></content:encoded>
		
		<series:name><![CDATA[HTML5 Conference 2015 特集]]></series:name>
	</item>
		<item>
		<title>基本的な要素・機能を提供するCore ElementsとMaterial Designを実現するPaper Elements</title>
		<link>/1000ch/12477/</link>
		<pubDate>Thu, 12 Feb 2015 04:00:00 +0000</pubDate>
		<dc:creator><![CDATA[泉水翔吾]]></dc:creator>
				<category><![CDATA[最新動向]]></category>
		<category><![CDATA[Material Design]]></category>
		<category><![CDATA[Polymer]]></category>
		<category><![CDATA[Web Components]]></category>

		<guid isPermaLink="false">/?p=12477</guid>
		<description><![CDATA[連載： 基礎からわかる Web Components 徹底解説 〜仕様から実装まで理解する〜 (4)この記事は、連載「基礎からわかるWeb Components徹底解説～仕様から実装まで理解する〜」の第4回目になります。...]]></description>
				<content:encoded><![CDATA[<div class="seriesmeta">連載： <a href="https://html5experts.jp/series/web-components-2/" class="series-214" title="基礎からわかる Web Components 徹底解説 〜仕様から実装まで理解する〜" data-wpel-link="internal">基礎からわかる Web Components 徹底解説 〜仕様から実装まで理解する〜</a> (4)</div><p>この記事は、連載「<a href="https://html5experts.jp/series/web-components-2/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">基礎からわかるWeb Components徹底解説～仕様から実装まで理解する〜</a>」の第4回目になります。今回は、前回紹介したGoogleが開発するWeb Componentsのライブラリ、Polymerを元に作られたコンポーネント群「Core Elements」と「Paper Elements」について紹介します。</p>

<h2>Core ElementsとPaper Elements</h2>

<p>Core ElementsとPaper ElementsはGoogleが開発するWeb Components群です。Core Elementsは、Webを構成する要素をWeb Componentsとして切り出し抽象化したものであり、Paper Elementsはデザインコンセプト<a href="http://www.google.com/design/spec/material-design/introduction.html" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">Material Design</a>をWebで実現します。</p>

<p>いずれもPolymerをベースに作られている他、各コンポーネントが異なるコンポーネントに依存したつくりになっているものもあります。アーカイブファイルの配布もされていますが、<a href="http://bower.io/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">Bower</a>であればインストール時に依存関係は自動で解決されるため、意識する必要はありません。</p>

<h2>インストールして実際に利用する例</h2>

<p>Core Elementsのひとつである<a href="https://www.polymer-project.org/docs/elements/core-elements.html#core-image" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer"><code>core-image</code></a>というコンポーネントを、Bowerを使ってインストールし、実際に使う例を以下に示します。<code>core-image</code>は通常の<code>img</code>タグにはない、画像のリサイズやプリロードといった機能を備えたWeb Componentsです。</p>

<p>まず、コマンドラインからBowerを使って<code>core-image</code>をインストールします。<code>bower.json</code>に依存情報を記録する場合は<code>--save</code>オプションを付けます。</p>

<p></p><pre class="crayon-plain-tag">$ bower install Polymer/core-image</pre><p></p>

<p>実行後は、デフォルトであれば<code>bower_components</code>フォルダ配下に<code>core-image</code>と、<code>core-image</code>が依存するサブリソースがダウンロードされています。<code>core-image</code>が依存するのはPolymer Coreのみですが、Polymer Coreが依存するリソースがさらに存在するので、それらもダウンロードされています。</p>

<p>ダウンロードした<code>core-image.html</code>をHTML内でロードすることで、<code>core-image</code>要素を使えるようになります。</p>

<p></p><pre class="crayon-plain-tag">&lt;html&gt;
  &lt;head&gt;
    &lt;link rel="import" href="bower_components/core-image/core-image.html"&gt;
  &lt;/head&gt;
  &lt;body&gt;
    &lt;core-image src="http://lorempixel.com/400/400"&gt;&lt;/core-image&gt;
  &lt;/body&gt;
&lt;/html&gt;</pre><p></p>

<p>サンプルでは、ダウンロードされたPolymer Coreを参照していませんが、ロードしているcore-image.htmlの中でPolymer Coreのインポートが行われているため、改めてPolymer Coreを読み込む必要はありません。</p>

<p>Polymerチームは、依存管理にBowerを使うことを推奨しています。自身でWeb Componentsを作成し、公開する場合は依存するリソースを<code>bower.json</code>に書き、コンポーネント内のサブリソースへの参照も、Bowerが使われることを意識するとよいでしょう。</p>

<h2>基本的な要素・機能を提供するCore Elements</h2>

<p>Core Elementsは、ユーザーインターフェースの基礎です。よく使われるけどブラウザネイティブには提供されていない機能や、Polymerの強力な機能との橋渡しとなるコンポーネントを提供します。後述のPaper Elementsの土台になっているように、拡張前提のコンポーネントも多くあります。</p>

<ul>
<li><a href="https://www.polymer-project.org/docs/elements/core-elements.html" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">Polymer core elements</a> Polymer公式サイトのCore Elementsのページ</li>
<li><a href="http://www.polymer-project.org/components/core-elements/demo.html" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">Core Elements Sampler</a> Core Elementsのサンプル集</li>
</ul>

<h3>UI関連のCore Elements</h3>

<p>UIに関するCore Elementsとしては、既存のHTMLでは提供されていないドロップダウンやオーバーレイといった汎用的なUIや、既存のUIの機能を補完しているコンポーネントが用意されています。</p>

<p>例えば、<a href="https://www.polymer-project.org/docs/elements/core-elements.html#core-dropdown" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer"><code>core-dropdown-menu</code></a>を使ったドロップダウンが挙げられます。ドロップダウンのUIは今や当たり前のように見かけますが、要件が出る度にイチから実装していたケースも多いのではないでしょうか。</p>

<p>以下は、<code>core-dropdown-menu</code>と<code>core-menu</code>及び<code>core-item</code>を組み合わせて実装するドロップダウンメニューの例（公式サイトから引用）です。</p>

<p></p><pre class="crayon-plain-tag">&lt;core-dropdown-menu label="Choose a pastry"&gt;
  &lt;core-dropdown class="dropdown"&gt;
    &lt;core-selector&gt;
      &lt;core-item label="Croissant"&gt;&lt;/core-item&gt;
      &lt;core-item label="Donut"&gt;&lt;/core-item&gt;
      &lt;core-item label="Financier"&gt;&lt;/core-item&gt;
      &lt;core-item label="Madeleine"&gt;&lt;/core-item&gt;
    &lt;/core-selector&gt;
  &lt;/core-dropdown&gt;
&lt;/core-dropdown-menu&gt;</pre><p></p>

<p>他にも以下のようなインターフェースが切り出されています。</p>

<ul>
<li><a href="https://www.polymer-project.org/docs/elements/core-elements.html#core-collapse" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">core-collapse</a> 折りたたみコンテンツ</li>
<li><a href="https://www.polymer-project.org/docs/elements/core-elements.html#core-drag-drop" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">core-drag-drop</a> ドラッグアンドドロップ</li>
<li><a href="https://www.polymer-project.org/docs/elements/core-elements.html#core-menu" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">core-menu</a> メニューアイテム</li>
<li><a href="https://www.polymer-project.org/docs/elements/core-elements.html#core-overlay" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">core-overlay</a> 他のコンテンツに覆いかぶさるオーバーレイ</li>
<li><a href="https://www.polymer-project.org/docs/elements/core-elements.html#core-tooltip" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">core-tooltip</a> ホバー時に表示されるツールチップ</li>
</ul>

<p>機能を補完している例としては、<a href="https://www.polymer-project.org/docs/elements/core-elements.html#core-input" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer"><code>core-input</code></a>があります。</p>

<p><code>core-input</code>は<code>is="core-input"</code>のように、ネイティブHTMLの拡張として利用します。拡張されたinput要素は、<code>aria-label</code>や<code>aria-disabled</code>といった<a href="https://developer.mozilla.org/ja/docs/Web/Accessibility/ARIA" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">ARIA</a>で定義されるアクセシビリティを自動で保管したり、フォームとしてサブミットされた時の値を<code>committedValue</code>として取得できるようになります。</p>

<p>他には前述の<code>core-image</code>も、後者に該当すると言えるでしょう。</p>

<h3>アニメーション関連のCore Elements</h3>

<p>Core ElementsにはUIパーツだけでなく、アニメーションを抽象化したコンポーネント群があります。その中核を成すのが<a href="https://www.polymer-project.org/docs/elements/core-elements.html#core-animation" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer"><code>core-animation</code></a>です。</p>

<p><code>core-animation</code>でアニメーションを定義し、<code>core-animation-keyframe</code>と<code>core-animation-prop</code>でアニメーションの具体的な挙動を指定します。以下は<code>core-animation</code>要素でアニメーションを定義する例（公式サイトから引用）です。</p>

<p></p><pre class="crayon-plain-tag">&lt;core-animation id="fadeout" duration="500"&gt;
  &lt;core-animation-keyframe&gt;
    &lt;core-animation-prop name="opacity" value="1"&gt;&lt;/core-animation-prop&gt;
  &lt;/core-animation-keyframe&gt;
  &lt;core-animation-keyframe&gt;
    &lt;core-animation-prop name="opacity" value="0"&gt;&lt;/core-animation-prop&gt;
  &lt;/core-animation-keyframe&gt;
&lt;/core-animation&gt;

&lt;div id="el"&gt;Fade me out&lt;/div&gt;

&lt;script&gt;
  var animation = document.getElementById('fadeout');
  animation.target = document.getElementById('el');
  animation.play();
&lt;/script&gt;</pre><p></p>

<p>ここではキーフレーム毎に透過度を変化させ、フェードアウトのアニメーションを宣言しています。そして、アニメーションさせたい要素を、<code>core-animation</code>の<code>target</code>属性に指定することでフェードアウトさせてます。これはJavaScriptのコードで命令的に行っています。</p>

<p>複数のアニメーションを組み合わせて使いたい場合は、<a href="https://www.polymer-project.org/docs/elements/core-elements.html#core-animation-group" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer"><code>core-animation-group</code></a>というグルーピングを担うコンポーネントもあります。</p>

<h3>ブラウザAPI関連のCore Elements</h3>

<p>提供しているのは、汎用的なアイコンやユーザーインターフェースといったビジュアルに関わる部分に限りません。Core ElementsではAjaxやキーボードアクションのハンドリング等、見た目には直接関わらない機能もWeb Componentsとして抽象化しています。</p>

<ul>
<li><a href="https://www.polymer-project.org/docs/elements/core-elements.html#core-a11y-keys" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">core-a11y-keys</a> キー押下のハンドリング</li>
<li><a href="https://www.polymer-project.org/docs/elements/core-elements.html#core-ajax" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">core-ajax</a> Ajaxの定義及びハンドリング</li>
<li><a href="https://www.polymer-project.org/docs/elements/core-elements.html#core-localstorage" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">core-localstorage</a> ローカルストレージへのアクセス</li>
</ul>

<p>今まではJavaScriptからそれぞれのAPIを実行し制御していた機能ですが、これらによって、他の要素との連携がPolymerが提供するデータバインディング機能などで容易になる他、HTMLに記述することで宣言的に挙動を定義していくことが可能になります。</p>

<p>以下はデータバインディングを利用して<code>input</code>要素に入力した値をローカルストレージに保存する例です。</p>

<p></p><pre class="crayon-plain-tag">&lt;input type="text" value="{{value}}"&gt;
&lt;core-localstorage name="localstorage-key" value="{{value}}"&gt;&lt;/core-localstorage&gt;</pre><p></p>

<p><code>core-localstorage</code>の<code>value</code>属性の値がローカルストレージに保存されるので、<code>input</code>の<code>value</code>とバインドすることで入力値がそのまま保存されるようになります。今まではイチからJavaScriptで制御していたことを考えれば、よりわかりやすく、そしてグッと楽になっています。</p>

<h2>Material Designを実現するPaper Elements</h2>

<p>Paper ElementsはMaterial DesignをWebで実現するWeb Components群です。Polymer Coreへ依存している他、Core Elementsをベースに構成されているコンポーネントが多くを占めています。</p>

<p><img src="/wp-content/uploads/2015/02/paper-ripple.png" alt="paper-ripple" width="1136" height="885" class="alignnone size-full wp-image-12496" srcset="/wp-content/uploads/2015/02/paper-ripple.png 640w, /wp-content/uploads/2015/02/paper-ripple-300x233.png 300w, /wp-content/uploads/2015/02/paper-ripple-1024x797.png 1024w, /wp-content/uploads/2015/02/paper-ripple-207x161.png 207w" sizes="(max-width: 1136px) 100vw, 1136px" /></p>

<p>Material Designについては、<a href="https://html5experts.jp/ahomu/9307/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">話題のMaterial DesignをWebで実現！Polymerで「Paper Elements」を試そう</a>という記事を一読するとよいでしょう。</p>

<ul>
<li><a href="https://www.polymer-project.org/docs/elements/paper-elements.html" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">Polymer paper elements</a> Polymer公式サイトのPaper Elementsのページ</li>
<li><a href="http://www.polymer-project.org/components/paper-elements/demo.html" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">Paper Elements Sampler</a> Paper Elementsのサンプル集</li>
</ul>

<h3>UI関連のPaper Elements</h3>

<p>UI関連のPaper Elementsとしては、Core ElementsのUIコンポーネントにMaterial Designを取り入れた要素が多くあります。これは要素の一覧を見比べてもらうとわかるかと思います。</p>

<p>以下は<a href="https://www.polymer-project.org/docs/elements/paper-elements.html#paper-dropdown-menu" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer"><code>paper-dropdown-menu</code></a>の利用例です。</p>

<p></p><pre class="crayon-plain-tag">&lt;paper-dropdown-menu label="Your favorite pastry"&gt;
  &lt;paper-dropdown class="dropdown"&gt;
    &lt;core-menu class="menu"&gt;
      &lt;paper-item&gt;Croissant&lt;/paper-item&gt;
      &lt;paper-item&gt;Donut&lt;/paper-item&gt;
      &lt;paper-item&gt;Financier&lt;/paper-item&gt;
      &lt;paper-item&gt;Madeleine&lt;/paper-item&gt;
    &lt;/core-menu&gt;
  &lt;/paper-dropdown&gt;
&lt;/paper-dropdown-menu&gt;</pre><p></p>

<p>このように、利用方法もほぼ同じです。Paper Elementsとして独自に拡張しているのは、影やエフェクトのdurationなどのMaterial Designの表現に関わる部分だけとも捉えられます。</p>

<h3>Material Designを体現するエフェクト</h3>

<p>影の動きや波紋のようなインタラクションや、奥行きを表現するZ座標のルールといった、特徴的なMaterial Designのコンセプトを担うのは、以下のコンポーネントです。</p>

<ul>
<li><a href="https://www.polymer-project.org/docs/elements/paper-elements.html#paper-ripple" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">paper-ripple</a> クリックした位置から波紋が広がるエフェクト</li>
<li><a href="https://www.polymer-project.org/docs/elements/paper-elements.html#paper-spinner" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">paper-spinner</a> 円状のスピナー</li>
<li><a href="https://www.polymer-project.org/docs/elements/paper-elements.html#paper-shadow" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">paper-shadow</a> 紙で持ち上げられ影がついたようなエフェクト</li>
</ul>

<p>特に<code>paper-ripple</code>と<code>paper-shadow</code>はMaterial Designのコンセプトの中核を担っており、Paper Elementsのほとんどが、この2つのいずれかに（あるいは両方に）依存したコンポーネントになっています。</p>

<h2>paper-shadowを利用する例</h2>

<p>実際に<code>paper-shadow</code>を取り入れてみます。以下は<code>paper-shadow</code>を使わずにレイアウトしています。</p>

<p><img src="/wp-content/uploads/2015/02/lp-without-shadow-1024x797.png" alt="lp-without-shadow" width="1024" height="797" class="alignnone size-large wp-image-12559" srcset="/wp-content/uploads/2015/02/lp-without-shadow-1024x797.png 1024w, /wp-content/uploads/2015/02/lp-without-shadow-300x233.png 300w, /wp-content/uploads/2015/02/lp-without-shadow-207x161.png 207w, /wp-content/uploads/2015/02/lp-without-shadow.png 640w" sizes="(max-width: 1024px) 100vw, 1024px" /></p>

<p><code>paper-shadow</code>を使うには、冒頭で解説したようにBowerを使ってインストールして、影を付けたい要素を<code>paper-shadow</code>タグで囲むだけです。</p>

<p></p><pre class="crayon-plain-tag">&lt;paper-shadow z="2"&gt;
  &lt;core-selector id="theme-selector" selected="default"&gt;
    &lt;paper-item name="arta"&gt;Arta&lt;/paper-item&gt;
    &lt;paper-item name="ascetic"&gt;Ascetic&lt;/paper-item&gt;
    &lt;paper-item name="color-brewer"&gt;Color Brewer&lt;/paper-item&gt;
    &lt;paper-item name="docco"&gt;Docco&lt;/paper-item&gt;
    ...
  &lt;/core-selector&gt;
&lt;/paper-shadow&gt;</pre><p></p>

<p>このコードの場合は<code>core-selector</code>を囲っていますが、Core Elementsである必要はありません。<code>div</code>でも<code>section</code>でも大丈夫です。適用すると以下のようになります。</p>

<p><img src="/wp-content/uploads/2015/02/lp-with-shadow-1024x797.png" alt="lp-with-shadow" width="1024" height="797" class="alignnone size-large wp-image-12560" srcset="/wp-content/uploads/2015/02/lp-with-shadow-1024x797.png 1024w, /wp-content/uploads/2015/02/lp-with-shadow-300x233.png 300w, /wp-content/uploads/2015/02/lp-with-shadow-207x161.png 207w, /wp-content/uploads/2015/02/lp-with-shadow.png 640w" sizes="(max-width: 1024px) 100vw, 1024px" /></p>

<p><a href="http://1000ch.github.io/syntax-highlight" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">サンプルページ</a>では、簡単ではありますが他のPaper Elementsも使っています。Paper Elementsを取り入れる例としては、<a href="https://html5experts.jp/girlie_mac/12359/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">PolymerでMaterial Designなチャットアプリを作ろう</a>という記事に、より実践的なチュートリアルがあります。</p>

<h2>Polymer Designer</h2>

<p>Core ElementsやPaper Elementsを試す手段として<a href="http://polymer-designer.appspot.com/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">Polymer Designer</a>があります。</p>

<p><img src="/wp-content/uploads/2015/02/polymer-designer.png" alt="polymer-designer" width="1136" height="885" class="alignnone size-full wp-image-12478" srcset="/wp-content/uploads/2015/02/polymer-designer.png 640w, /wp-content/uploads/2015/02/polymer-designer-300x233.png 300w, /wp-content/uploads/2015/02/polymer-designer-1024x797.png 1024w, /wp-content/uploads/2015/02/polymer-designer-207x161.png 207w" sizes="(max-width: 1136px) 100vw, 1136px" /></p>

<p>Polymer Designerではブラウザ上で、Core ElementsやPaper Elementsをドラッグアンドドロップで配置し、データバインディング等もGUI上で行いコンポーネントを作成することが可能なツールです。Web上でお手軽に試したい場合には、こちらを使うのもよいでしょう。</p>

<p>使い方については<a href="https://html5experts.jp/1000ch/8906/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">Web Componentsが変えるWeb開発の未来</a>という記事で触れています。</p>

<h2>おわりに</h2>

<p>Core ElementsとPaper Elementsの概要・使い方について紹介しました。Web Componentsを使ってWebページの基礎を組み立てるならCore Elementsは便利ですし、Material DesignをWebに取り入れるには、Paper Elementsが既にデファクトスタンダードと言えるかもしれません。</p>

<p>使う分にはもちろん便利なCore ElementsとPaper Elementsですが、興味があればGitHubで公開されているソースコードを見てみることをオススメします。どういった設計でどのように抽象化しているかを見るのも、今後Web Componentsを自分で作っていく上できっと参考になるはずです。</p>
]]></content:encoded>
		
		<series:name><![CDATA[基礎からわかる Web Components 徹底解説 〜仕様から実装まで理解する〜]]></series:name>
	</item>
		<item>
		<title>PolymerでMaterial Designなチャットアプリを作ろう</title>
		<link>/girlie_mac/12359/</link>
		<pubDate>Tue, 27 Jan 2015 01:29:37 +0000</pubDate>
		<dc:creator><![CDATA[Tomomi Imura]]></dc:creator>
				<category><![CDATA[プログラミング]]></category>
		<category><![CDATA[Polymer]]></category>
		<category><![CDATA[Web Components]]></category>

		<guid isPermaLink="false">/?p=12359</guid>
		<description><![CDATA[今年注目のオープンWebテクノロジーのひとつに、Web Componentsが挙げられると思います。HTML5Experts.jpでも今まで幾度も関連記事、Polymer.jsについての記事が紹介されてきました。今回は実...]]></description>
				<content:encoded><![CDATA[<p>今年注目のオープンWebテクノロジーのひとつに、Web Componentsが挙げられると思います。HTML5Experts.jpでも今まで幾度も関連記事、Polymer.jsについての記事が紹介されてきました。今回は実際に、PolymerとMaterial Designのデザインコンセプトを用いて、視覚的にもユーザエクスペリエンスにも優れたチャットアプリを実際に作ってみましょう。</p>

<p><img src="/wp-content/uploads/2015/01/paper-chat-cover.png" alt="Material Design and Polymer" width="1360" height="600" class="aligncenter size-full wp-image-12358" srcset="/wp-content/uploads/2015/01/paper-chat-cover.png 640w, /wp-content/uploads/2015/01/paper-chat-cover-300x132.png 300w, /wp-content/uploads/2015/01/paper-chat-cover-1024x451.png 1024w, /wp-content/uploads/2015/01/paper-chat-cover-207x91.png 207w" sizes="(max-width: 1360px) 100vw, 1360px" /></p>

<p>まず始める前にこのライブデモ、<a href="http://pubnub.github.io/paper-chat/index.html" target="_blank" data-wpel-link="external" rel="follow external noopener noreferrer">Kitteh Anonymous</a>をデスクトップまたはモバイルのモダンブラウザで実際に試してみてください。ここでは、このデモの簡略版である<a href="http://pubnub.github.io/paper-chat/lite.html" target="_blank" data-wpel-link="external" rel="follow external noopener noreferrer">Liteバージョン</a>を実際に作成する方法をステップ・バイ・ステップで紹介したいと思います。</p>

<h3>必要な知識</h3>

<ul>
    <li><a href="https://www.polymer-project.org/" target="_blank" data-wpel-link="external" rel="follow external noopener noreferrer">Polymer</a>の基礎知識</li>
    <li>パッケージマネージャ、<a href="https://www.polymer-project.org/docs/start/getting-the-code.html#using-bower" target="_blank" data-wpel-link="external" rel="follow external noopener noreferrer">Bower</a>の基本的な使い方（Polymerと依存するファイルをインストール、アップデートするのに使いますが、必ずしも使う必要はありません）</li>

</ul>

<p>泉水翔吾さんの記事、<a href="https://html5experts.jp/1000ch/11905/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">Web Componentsを簡単・便利にするライブラリ「Polymer」を使いこなそう</a>や、佐藤歩さんの<a href="https://html5experts.jp/ahomu/9307/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">話題のMaterial DesignをWebで実現！Polymerで「Paper Elements」を試そう</a>を先に読むのをおすすめします。</p>

<h3>PolymerとWebスタンダード</h3>

<p>ちまたに数多く存在する、JavaScript UI library。<a href="https://www.polymer-project.org/" target="_blank" data-wpel-link="external" rel="follow external noopener noreferrer">Polymer</a>も単にまたそのひとつ、と思うかもしれません。しかしPolymerが他と違うのは、これがW3C WebプラットフォームプリミティブのWeb Componentsを基礎に作られていることです。このWeb Componentsファミリーに含まれるものに</p>

<ul>
    <li><a href="http://w3c.github.io/webcomponents/spec/shadow/" target="_blank" data-wpel-link="external" rel="follow external noopener noreferrer">Shadow DOM</a></li>
    <li><a href="http://w3c.github.io/webcomponents/spec/custom/" target="_blank" data-wpel-link="external" rel="follow external noopener noreferrer">Custom Elements</a></li>
    <li><a href="http://w3c.github.io/webcomponents/spec/imports/" target="_blank" data-wpel-link="external" rel="follow external noopener noreferrer">HTML Imports</a></li>
</ul>

<p>などが挙げられます。</p>

<p>そしてPolymerに含まれる<pre class="crayon-plain-tag">webcomponents.js</pre> は W3C DOM4の<a href="http://www.w3.org/TR/dom/#mutation-observers" target="_blank" data-wpel-link="external" rel="follow external noopener noreferrer">DOM mutation observers</a>や ECMAScript standardsである <pre class="crayon-plain-tag">Object.observe()</pre> のPolyfillの役目を果たしています。</p>

<h3>レゴブロックのようにWebを構築しよう</h3>

<p><img src="/wp-content/uploads/2015/01/lego.png" alt="lego" width="150" class="alignright size-full wp-image-12352" srcset="/wp-content/uploads/2015/01/lego.png 300w, /wp-content/uploads/2015/01/lego-261x300.png 261w, /wp-content/uploads/2015/01/lego-180x207.png 180w" sizes="(max-width: 300px) 100vw, 300px" />
Polymer webコンポーネントはカプセル化された何度も再利用できるコンポーネント。まるでレゴで家を構築するかのように、既存のパーツを使ったり自分で組み立てたパーツを使ったりと、いろいろなパーツを組み合わせてWebアプリを作ることができます。</p>

<p>実際にPolymerでアプリを作るには、まず必要な要素をインポートしてから使うことになります。</p>

<p></p><pre class="crayon-plain-tag">&lt;!-- Import element --&gt; 
&lt;link rel="import" href="paper-fab"&gt; 
... 
&lt;!-- Use element --&gt; 
&lt;paper-fab icon="send"&gt;&lt;/paper-fab&gt;</pre><p></p>

<h3>Material DesignとPolymerの関係</h3>

<p><a href="http://www.google.com/design/spec/material-design" target="_blank" data-wpel-link="external" rel="follow external noopener noreferrer">Material Design</a>は、既存のどのスクリーンサイズやデバイスにでも対応できる、ビジュアルとインタラクションデザインにすぐれたデザインスペックで、もともとはAndroid 5.0 Lollipop用にデザインされたものが、のちにWeb用としてPolymerのPaper Elementsとして適応されるようにました。</p>

<h2>1. Paper Elementsを使ってみよう</h2>

<p>さて実際にこれらを使って自分のアプリを作ってみましょう。 まず、Polymerをインストール、そしてアプリ構築に必要なコンポーネントをインポートします。</p>

<h3>1.1. Polymerをインストール</h3>

<p><pre class="crayon-plain-tag">$ bower install --save Polymer/polymer</pre></p>

<p>これで必要最低限のファイルがそろいます。</p>

<p><img src="/wp-content/uploads/2015/01/install-polymer.png" alt="polymer file structure" width="1032" height="443" class="aligncenter size-full wp-image-12357" srcset="/wp-content/uploads/2015/01/install-polymer.png 640w, /wp-content/uploads/2015/01/install-polymer-300x128.png 300w, /wp-content/uploads/2015/01/install-polymer-1024x439.png 1024w, /wp-content/uploads/2015/01/install-polymer-207x88.png 207w" sizes="(max-width: 1032px) 100vw, 1032px" /></p>

<p>インストールが終わったら、index.htmlの <pre class="crayon-plain-tag">&lt;head&gt;</pre> セクションに、 <pre class="crayon-plain-tag">webcomponents.min.js</pre> のみをロードさせます。</p>

<p></p><pre class="crayon-plain-tag">&lt;!DOCTYPE html&gt; 
&lt;html&gt; 
  &lt;head&gt; 
    &lt;script src="bower_components/webcomponentsjs/webcomponents.min.js"&gt;&lt;/script&gt; 
  &lt;/head&gt; 
  &lt;body&gt;
...</pre><p></p>

<h3>1.2. UI コンポーネントをインポート</h3>

<p>このデモのUIには、いくつかのPolymer CoreとPaper Elements、そして自作のカスタム要素が使われています。</p>

<ol>
    <li>core-scaffold (レスポンシブレイアウトを構成するheader、toolbar、menuなどがすでに揃った骨組み)</li>
    <li>core-item</li>
    <li>paper-input</li>
    <li>paper-fab</li>
    <li>カスタム (のちに作成しましょう)</li>
</ol>

<p><img src="/wp-content/uploads/2015/01/md-polymer-components.png" alt="polymer paper elements" width="855" height="345" class="aligncenter size-full wp-image-12356" srcset="/wp-content/uploads/2015/01/md-polymer-components.png 640w, /wp-content/uploads/2015/01/md-polymer-components-300x121.png 300w, /wp-content/uploads/2015/01/md-polymer-components-207x83.png 207w" sizes="(max-width: 855px) 100vw, 855px" /></p>

<p>Bowerを使って４つのcomponentsをインストールします。</p>

<p></p><pre class="crayon-plain-tag">$ bower install Polymer/core-scaffold 
$ bower install Polymer/core-item 
$ bower install Polymer/paper-input 
$ bower install Polymer/paper-fab</pre><p></p>

<p>インストールが終わったら、これらをHTML importsを使ってインポートします。</p>

<p></p><pre class="crayon-plain-tag">&lt;script src="bower_components/webcomponentsjs/webcomponents.min.js"&gt;&lt;/script&gt;   

&lt;link rel="import" href="bower_components/core-scaffold/core-scaffold.html"&gt; 
&lt;link rel="import" href="bower_components/core-item/core-item.html"&gt; 
&lt;link rel="import" href="bower_components/paper-input/paper-input.html"&gt; 
&lt;link rel="import" href="bower_components/paper-fab/paper-fab.html"&gt;</pre><p></p>

<p>このようにすることで、これらの要素がDOM上で使われる前に依存ファイルを含めて全てがしっかりロードされることになります。</p>

<h3>1.3. ベーシックUIの構成</h3>

<p>まず、 <pre class="crayon-plain-tag">&lt;core-scaffold&gt;</pre> を使って、ベースとなるレイアウトを構成しましょう。この要素は、レスポンシブな骨組みを簡単に作る(scaffold）ことができる便利な要素で、サブコンポーネントとして <pre class="crayon-plain-tag">&lt;core-header-panel&gt;</pre> 、 
<pre class="crayon-plain-tag">&lt;core-toolbar&gt;</pre> 
、 <pre class="crayon-plain-tag">&lt;core-drawer-panel&gt;</pre> などがすでに含まれています。</p>

<p></p><pre class="crayon-plain-tag">&lt;body fullbleed unresolved&gt;
  &lt;core-scaffold&gt;

    &lt;!-- ドロウアーパネル --&gt;
    &lt;core-header-panel navigation flex&gt;
        &lt;core-toolbar class="tall"&gt;
            &lt;!-- an avatar and username will be here --&gt;
        &lt;/core-toolbar&gt;
    &lt;/core-header-panel&gt;

    &lt;!-- アプリのタイトル --&gt;
    &lt;div tool layout horizontal flex&gt;
        &lt;span flex&gt;Kitteh Anonymous&lt;/span&gt;
        &lt;core-icon icon="account-circle"&gt;&lt;/core-icon&gt;
        &lt;span&gt;&lt;!-- number of people online --&gt;&lt;/span&gt; 
    &lt;/div&gt;

    &lt;!-- メインコンテンツ --&gt;
    &lt;div flex&gt;
            ...
    &lt;/div&gt;
  &lt;/core-scaffold&gt;
&lt;/body&gt;</pre><p></p>

<p>これでアプリのコア・ストラクチャーができました。  <pre class="crayon-plain-tag">&lt;core-scaffold&gt;</pre> は実際はこの例よりもより簡単に使うとこができるのですが、このデモでは左のドロウアー部分のヘッダの高さをかえて、ベーシックスタイルよりも少し凝ったデザインにしています。</p>

<p>ここで <pre class="crayon-plain-tag">&lt;body&gt;</pre> に見慣れない属性が使われていることにお気づきかと思います。 この <pre class="crayon-plain-tag">fullbreed</pre> はbodyをビューポートにぴったり合わせるため、 <pre class="crayon-plain-tag">unresolved</pre> はスタイライズされていないコンテンツが一瞬画面に表示される現象(FOUC)を防ぐために使われています。</p>

<p>他、要素の要所に <pre class="crayon-plain-tag">flex</pre> 属性が使われています。PolymerはCSSスタンダードのFlexboxを属性として使っており、この子要素に <pre class="crayon-plain-tag">layout horizontal | vertical</pre> が使われた時、この子要素が横または縦に、スクリーンにある分だけのスペースに引き伸ばされます。下の図を見てください。ヘッダUIのタイトル部分が引き伸ばされているため、右のアイコンと数字がきれいに右端に寄せて表示されています。</p>

<p><img src="/wp-content/uploads/2015/01/flex.png" alt="flex" width="495" height="155" class="aligncenter size-full wp-image-12355" srcset="/wp-content/uploads/2015/01/flex.png 495w, /wp-content/uploads/2015/01/flex-300x93.png 300w, /wp-content/uploads/2015/01/flex-207x64.png 207w" sizes="(max-width: 495px) 100vw, 495px" /></p>

<h3>1.4. 個々のUI Elementsを使う</h3>

<p>次に、このベースレイアウトの中に、先ほど一緒にインポートした個々のUIパーツを使います。 例えば次に示すコードサンプルでは、スクリーン横幅にあわせスタイライズされたインプットと、送信ボタンを表示しています。</p>

<p>二重カーリーブラケットに囲まれた <pre class="crayon-plain-tag">{{input}}</pre> 、 <pre class="crayon-plain-tag">{{sendMyMessage}}</pre>に注目してださい。これは式や <pre class="crayon-plain-tag">on-</pre>で始まるイベントハンドラとして使われます。次のチャプターで簡単に説明します。</p>

<p></p><pre class="crayon-plain-tag">&lt;!-- メインコンテンツ --&gt;   
&lt;div class="send-message" layout horizontal&gt;
 &lt;paper-input flex label="Type message..." id="input" value="{{input}}"&gt;&lt;/paper-input&gt;
 &lt;paper-fab icon="send" id="sendButton" on-tap="{{sendMyMessage}}"&gt;&lt;/paper-fab&gt; 
&lt;/div&gt;</pre><p></p>

<p>実際のアプリの中でコンポーネントがどのようにインポートされているかは、GitHub Repo上の<a href="https://github.com/pubnub/paper-chat/blob/gh-pages/lite.html" target="_blank" data-wpel-link="external" rel="follow external noopener noreferrer">lite.html</a>のソースコードを見て確認してみてください。</p>

<h3>1.5. データバインディング</h3>

<p>PolymerはHTMLの新スタンダードである <pre class="crayon-plain-tag">&lt;template&gt;</pre>を使って、宣言的で双方向のデータバインディングをサポートしています。 Polymerのデータバインディングにはいくつか方法があるのですが、ここでは <pre class="crayon-plain-tag">&lt;template&gt;</pre> でアプリの全コードを囲むことによって自動バインディングを可能にしています。</p>

<p></p><pre class="crayon-plain-tag">&lt;body fullbleed unresolved&gt;
  &lt;template is="auto-binding"&gt;
    &lt;core-scaffold&gt;
      ...
    &lt;/core-scaffold&gt;
  &lt;/template&gt;
&lt;/body&gt;</pre><p></p>

<p>これで、前チャプター(1.4)で既出の<pre class="crayon-plain-tag">paper-input</pre> の例にあるように、ユーザが入力する値を<pre class="crayon-plain-tag">{{input}}</pre>を使って得ることができます。</p>

<p></p><pre class="crayon-plain-tag">var template = document.querySelector('template[is=auto-binding]');
doSomething(template.input);</pre><p></p>

<p>他、このデータモデルを使えば、要素を繰り返し使うようなマークアップを簡略化するなどということもできるのです。 実際にドロウアーパネルUIの中に、<pre class="crayon-plain-tag">core-item</pre>を使ったリストを作成してみましょう。</p>

<p></p><pre class="crayon-plain-tag">&lt;template repeat="{{item in items}}"&gt;
  &lt;core-item icon="{{item.icon}}" label="{{item.title}}"&gt;&lt;/core-item&gt;
&lt;/template&gt;</pre><p></p>

<p><pre class="crayon-plain-tag">core-item</pre>のコンテンツは、JavaScript側で、items配列を使ってオブジェクトで指定します。 ここでは、<pre class="crayon-plain-tag">&lt;core-icons&gt;</pre>で既に用意されている<a href="http://www.polymer-project.org/components/core-icons/demo.html" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">アイコンのセット</a>を使っています。</p>

<p></p><pre class="crayon-plain-tag">template.items = [
  {title: 'Uno', icon: 'cloud'},
  {title: 'Dos', icon: 'polymer'},
  {title: 'Tres', icon: 'favorite'}
];</pre><p></p>

<p>これで、モデルを生成・変更した時に自動的にテンプレートにインスタンスが生成され、DOM上には下の図のように表示されます。
<img src="/wp-content/uploads/2015/01/core-item.png" alt="core-item" width="257" height="186" class="aligncenter size-full wp-image-12351" srcset="/wp-content/uploads/2015/01/core-item.png 257w, /wp-content/uploads/2015/01/core-item-207x149.png 207w" sizes="(max-width: 257px) 100vw, 257px" /></p>

<h2>2. カスタム要素の作成</h2>

<p>メインUIとなる部分にチャットの会話を表示させましょう。このUIパーツには、アバター、ユーザーID、チャットのテキストが表示させるようにしたいのですが、Polymer CoreにもPaperにもそういったバーツは存在しません。ですので自分でカスタム要素を作ってみましょう。</p>

<p>まず新規のHTMLファイルを作成します。ここではこのファイル名を、<pre class="crayon-plain-tag">x-chat-list.html</pre>とします。</p>

<p>このカスタム要素は、属性、<pre class="crayon-plain-tag">avatar</pre>、<pre class="crayon-plain-tag">color</pre>、 <pre class="crayon-plain-tag">username</pre>、<pre class="crayon-plain-tag">text</pre>を扱います。</p>

<p><img src="/wp-content/uploads/2015/01/x-chat-list.png" alt="custom element" width="450" height="188" class="aligncenter size-full wp-image-12354" srcset="/wp-content/uploads/2015/01/x-chat-list.png 450w, /wp-content/uploads/2015/01/x-chat-list-300x125.png 300w, /wp-content/uploads/2015/01/x-chat-list-207x86.png 207w" sizes="(max-width: 450px) 100vw, 450px" /></p>

<p>ここでは、カスタム要素の作製法を一から説明はしませんが、簡略化されたカスタム要素は次のようになります。</p>

<p></p><pre class="crayon-plain-tag">&lt;polymer-element name="x-chat-list" attributes="avatar color username text"&gt;
  &lt;template&gt;
  &lt;section class="user-list" layout horizontal&gt;
    &lt;div class="avatar {{color}}" style="background-image: url({{avatar}})"&gt;&lt;/div&gt;
    &lt;div flex&gt;
      &lt;div class="username"&gt;{{username}}&lt;/div&gt;
      &lt;div class="text"&gt;{{text}}&lt;/div&gt;
    &lt;/div&gt;
  &lt;/section&gt;
  &lt;/template&gt;
  &lt;script&gt;
    Polymer('x-chat-list', { // デフォルト値を指定
      avatar: '', 
      color: '',
      username: '',
      text: ''
    });
  &lt;/script&gt;
&lt;/polymer-element&gt;</pre><p></p>

<p>この例ではわかりやすく見せるために、 <pre class="crayon-plain-tag">&lt;style&gt;...&lt;/style&gt;</pre>部分が省略されていますが実際にUIのカスタム要素を作るにはCSSは不可欠でしょう。CSSを含む全ソースコードの<pre class="crayon-plain-tag">x-chat-list.html</pre> は<a href="https://github.com/pubnub/paper-chat/blob/gh-pages/x-chat-list.html" target="_blank" data-wpel-link="external" rel="follow external noopener noreferrer">GitHub Repo</a>で見てください。</p>

<p>できあがったら<pre class="crayon-plain-tag">index.html</pre>に戻って、このカスタム要素をインポートします。</p>

<p></p><pre class="crayon-plain-tag">&lt;link rel="import" href="x-chat-list.html"&gt;</pre><p></p>

<p></p><pre class="crayon-plain-tag">&lt;div flex class="chat-list"&gt;
  &lt;template repeat="{{message in messages}}"&gt;
    &lt;x-chat-list color="{{message.color}}" 
                 avatar="{{message.avatar}}" 
                 username="{{message.uuid}}" 
                 text="{{message.text}}"&gt;&lt;/x-chat-list&gt;
  &lt;/template&gt;
&lt;/div&gt;</pre><p></p>

<p>データは実際の生のチャットの会話を、PubNubデータ・ストリームサービスを使って表示させます。詳しくは次のセクションで説明します。</p>

<p>かなりはしょってしまいましたが、カスタム要素を作る詳しい説明は<a href="https://www.polymer-project.org/docs/start/tutorial/step-2.html" target="_blank" data-wpel-link="external" rel="follow external noopener noreferrer">公式のドキュメント</a>を参照してください。</p>

<h2>3.PubNub Elementでメッセージの送信・受信をする</h2>

<p><img src="/wp-content/uploads/2015/01/pubnub-polymer.png" alt="pubnub-element" width="231" height="160" class="aligncenter size-full wp-image-12353" srcset="/wp-content/uploads/2015/01/pubnub-polymer.png 231w, /wp-content/uploads/2015/01/pubnub-polymer-207x143.png 207w" sizes="(max-width: 231px) 100vw, 231px" /></p>

<p>アプリのUI部分はすべて完成しましたので、今度はチャットルームそのものを作ってみましょう。データの送受信は<a href="http://pubnub.com/" target="_blank" data-wpel-link="external" rel="follow external noopener noreferrer">PubNub</a>が提供するリアルタイム・データストリームのPolymerエレメント版である、 <pre class="crayon-plain-tag">&lt;pubnub-element&gt;</pre> を使います。 今まで使った要素と違うのはこの要素にはユーザインターフェイスが伴わないことです。では何をしてくれるのかというと、要素でカプセル化されたPubNub APIがクラウドでデータのpublish / subscribeのやりとりをはたしてくれるのです。なので私たちがサーバを立てる必要はありません。</p>

<p><pre class="crayon-plain-tag">&lt;pubnub-element&gt;</pre>はサードパーティAPIを使用しますので、まず自分のAPI keysを作成しておく必要があります。 <a href="http://www.pubnub.com/get-started/" target="_blank" data-wpel-link="external" rel="follow external noopener noreferrer">PubNubアカウントはここから取得してください</a>。短時間試してみたいだけならば、<pre class="crayon-plain-tag">publish_key</pre>と<pre class="crayon-plain-tag">publish_key</pre>を<em>demo</em>にして使うこともできます。</p>

<h3>3.1. &lt;pubnub-element&gt;をインストール・インポート</h3>

<p>インストールは、他の要素同様にBowerを使うことができます。</p>

<p><pre class="crayon-plain-tag">$ bower install --save pubnub-polymer</pre></p>

<p>インストール後は<pre class="crayon-plain-tag">index.html</pre>でこれをインポートします。</p>

<p></p><pre class="crayon-plain-tag">&lt;link rel="import" href="bower_components/pubnub-polymer/pubnub-element.html"&gt;</pre><p></p>

<h3>3.2. &lt;pubnub-element&gt;を使う</h3>

<p>まず、 <pre class="crayon-plain-tag">&lt;core-pubnub&gt;</pre>を使ってクライアントの初期化をします。</p>

<p></p><pre class="crayon-plain-tag">&lt;core-pubnub publish_key="your_pub_key" subscribe_key="your_sub_key" uuid="{{uuid}}"&gt;
&lt;/core-pubnub&gt;</pre><p></p>

<p>ここで使われる<pre class="crayon-plain-tag">uuid</pre>とはチャットルームの各ユーザのユニークIDで、ランダムな文字列を使います。このアプリでは、おのおののユーザがアクセスした時に、<em>navy-siamese</em>（濃紺色・シャム猫）のように、色と猫の種類の文字列の組み合わせで構成されたIDが与えられるようにします。</p>

<p></p><pre class="crayon-plain-tag">var randomColor = function() {   
  var colors = ['navy', 'slate', 'olive',...];   
  return colors[(Math.random() * colors.length) &gt;&gt;&gt; 0];
};

var randomCat = function() { ... }; 

template.uuid = randomColor() + '-' + randomCat();</pre><p></p>

<p><img src="/wp-content/uploads/2015/01/cats.png" alt="cat avatars" width="626" height="46" class="aligncenter size-full wp-image-12350" srcset="/wp-content/uploads/2015/01/cats.png 626w, /wp-content/uploads/2015/01/cats-300x22.png 300w, /wp-content/uploads/2015/01/cats-207x15.png 207w" sizes="(max-width: 626px) 100vw, 626px" /></p>

<h3>3.3. メッセージの送信</h3>

<p><pre class="crayon-plain-tag">&lt;core-pubnub-publish&gt;</pre>はチャンネルのサブスクライバー全てにメッセージを送信することができる要素です。</p>

<p></p><pre class="crayon-plain-tag">&lt;core-pubnub publish_key="demo" subscribe_key="demo"&gt;
  &lt;core-pubnub-publish id="pub" channel="polymer-chat" message="Hello"&gt;
  &lt;/core-pubnub-publish&gt;
&lt;/core-pubnub&gt;</pre><p></p>

<p>では、ユーザが文字を入力して送信ボタン( <pre class="crayon-plain-tag">&lt;paper-fab&gt;</pre> )をタップした時に、そのメッセージをサーバに送るコードを書きましょう。 Polymerは、<pre class="crayon-plain-tag">on-*</pre>イベントハンドラを使うので、この場合 <pre class="crayon-plain-tag">on-tap</pre>イベントを用いて<pre class="crayon-plain-tag">&lt;paper-fab&gt;</pre>がこのアクションを引き起こすことができるようにしてみます。</p>

<p></p><pre class="crayon-plain-tag">&lt;paper-fab icon="send" on-tap="{{sendMyMessage}}"&gt;&lt;/paper-fab&gt;</pre><p></p>

<p></p><pre class="crayon-plain-tag">template.sendMyMessage = function(e) {
  if(!template.input) return; // 入力フィールドが空の場合は何もしない

  template.$.pub.message = {
    uuid: uuid, 
    avatar: avatarUrl,
    color: color, 
    text: template.input  
  };
  template.$.pub.publish();
};</pre><p></p>

<p>これでユーザの情報とメッセージテキストが、サーバに送られました。次はすべてのユーザがこれを受信して、内容ををDOMに表示させてみましょう。</p>

<h3>3.4. 受信データのリアルタイムバインディング</h3>

<p>ネットワークに送られたメッセージは <pre class="crayon-plain-tag">&lt;core-pubnub-subscribe&gt;</pre>要素を使ってクライアント側で受信することができます。</p>

<p></p><pre class="crayon-plain-tag">&lt;core-pubnub-subscribe 
  channel="polymer-chat" 
  id="sub" 
  messages="{{messages}}" 
  on-callback="{{subscribeCallback}}"&gt;</pre><p></p>

<p>ここでの<pre class="crayon-plain-tag">messages</pre>属性は受信されたメッセージオブジェクトの配列が含まれています。ではここで受け取ったデータを先ほど作成した<pre class="crayon-plain-tag">&lt;x-chat-list&gt;</pre>カスタム要素を使って表示させましょう。 実は先のチャプター２で、既に <pre class="crayon-plain-tag">messages</pre> 配列のインスタンスが使われていることに気がついたでしょうか？ <pre class="crayon-plain-tag">messages="{{messages}}"</pre> 属性が&lt; <pre class="crayon-plain-tag">core-pubnub-subscribe&gt;</pre> と <pre class="crayon-plain-tag">&lt;x-chat-list&gt;</pre>の間で双方向バインディングがすでに行われているのです。なので、自動的にDOM生成を行ってチャットの内容を表示することができるのです！</p>

<p>ではもう一度、<pre class="crayon-plain-tag">&lt;x-chatlist&gt;</pre>を見てみましょう。</p>

<p></p><pre class="crayon-plain-tag">&lt;div flex class="chat-list"&gt;
  &lt;template repeat="{{message in messages}}"&gt;
    &lt;x-chat-list 
      color="{{message.color}}" 
      avatar="{{message.avatar}}" 
      username="{{message.uuid}}" 
      text="{{message.text}}"&gt;&lt;/x-chat-list&gt;
  &lt;/template&gt;
&lt;/div&gt;</pre><p></p>

<p>メッセージが受信された際には、<pre class="crayon-plain-tag">&lt;core-pubnub-subscribe&gt;</pre>のコールバック、<pre class="crayon-plain-tag">on-callback</pre>が発生します。 このチャットの配列は時間順に並べられているので、新しいメッセージはスクリーンの一番下に表示されることになります。これではユーザの使い勝手が悪いので、コールバック発生時に自動的に最新チャットまでスクロールさせることにしましょう。</p>

<p></p><pre class="crayon-plain-tag">template.subscribeCallback = function(e) {
  template.async(function(){
    var chatDiv = document.querySelector('.chat-list');
    chatDiv.scrollTop = chatDiv.scrollHeight; // scroll to bottom
  });
};</pre><p></p>

<p>これで、PolymerでMaterial Designの美しいデザインを使った簡単なチャットルームが完成しました！</p>

<p>このチュートリアルではわかりやすくするために、<a href="http://pubnub.github.io/paper-chat/index.html" target="_blank" data-wpel-link="external" rel="follow external noopener noreferrer">デモ</a>で使われているすべてのフィーチャーについてや、Shadow DOMのスタイリングについての説明は省略してあるので、さらに知りたい方は是非、<a href="https://github.com/pubnub/paper-chat" target="_blank" data-wpel-link="external" rel="follow external noopener noreferrer">GitHub のRepo</a>で確認してみてください。</p>

<p>デモとチュートリアル、楽しんでいただけたなら幸いです！Happy coding!</p>

<p><img src="/wp-content/uploads/2015/01/paper-chat.gif" alt="polymer pubnub chat app animated gif" width="280" height="280" class="aligncenter size-full wp-image-12364" /></p>
]]></content:encoded>
			</item>
		<item>
		<title>HTML5 Experts.jp 2014年の年間読まれた記事ランキングTOP20！</title>
		<link>/yusuke-naka/11973/</link>
		<pubDate>Fri, 26 Dec 2014 06:47:16 +0000</pubDate>
		<dc:creator><![CDATA[仲 裕介]]></dc:creator>
				<category><![CDATA[最新動向]]></category>
		<category><![CDATA[AngularJS]]></category>
		<category><![CDATA[Material Design]]></category>
		<category><![CDATA[UX]]></category>
		<category><![CDATA[Web Components]]></category>
		<category><![CDATA[Web Starter Kit]]></category>
		<category><![CDATA[ionic]]></category>
		<category><![CDATA[three.js]]></category>

		<guid isPermaLink="false">/?p=11973</guid>
		<description><![CDATA[日本初のHTML5技術専門サイト「HTML5 Experts.jp」も開設から1年5カ月が経ちました。2014年は時事ネタをタイムリーに取り入れた特集記事を充実させて参りましたが、皆様、お楽しみいただけましたでしょうか？...]]></description>
				<content:encoded><![CDATA[<p>日本初のHTML5技術専門サイト「HTML5 Experts.jp」も開設から1年5カ月が経ちました。2014年は時事ネタをタイムリーに取り入れた特集記事を充実させて参りましたが、皆様、お楽しみいただけましたでしょうか？今年最後の記事は、記事公開後１週間の閲覧数（PV）をもとに、2014年の年間読まれた記事ランキングTOP20！をお届けします。</p>

<h2>年間読まれた記事ランキングTOP20！</h2>

<p><strong>＜1位＞</strong><br>
<a href="https://html5experts.jp/furoshiki/8582/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer"><img alt="1" src="/wp-content/uploads/2014/07/709f657b9e0fe7c6dc483643a3c959b2.png" width="207" height="156" class="alignleft size-full"></a>
<strong><a href="https://html5experts.jp/furoshiki/8582/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">Googleはなぜモバイルに力を入れるのか？これからのWebパフォーマンスで注力すべきポイント</a></strong><br>
── <a href="https://html5experts.jp/furoshiki/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">川田寛</a></p>

<p><br><br></p>

<p><strong>＜2位＞</strong><br>
<a href="https://html5experts.jp/girlie_mac/8384/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer"><img alt="2" src="/wp-content/uploads/2014/07/devtools-device-mode-screencast.jpg" width="207" height="156" class="alignleft size-full"></a>
<strong><a href="https://html5experts.jp/girlie_mac/8384/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">モバイルWeb開発に役立つ！Chrome DevToolsの新機能「デバイスモード」</a></strong><br>
── <a href="https://html5experts.jp/girlie_mac/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">Tomomi Imura</a></p>

<p><br><br></p>

<p><strong>＜3位＞</strong><br>
<a href="https://html5experts.jp/nakajmg/8931/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer"><img alt="2" src="/wp-content/uploads/2014/08/wsk_0.png" width="207" height="156" class="alignleft size-full"></a>
<strong><a href="https://html5experts.jp/nakajmg/8931/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">Googleのベストプラクティスに沿ったモダンな製作の出発点「Web Starter Kit」 </a></strong><br>
── <a href="https://html5experts.jp/nakajmg/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">中島 直博</a></p>

<p><br><br></p>

<p><strong>＜4位＞</strong><br>
<a href="https://html5experts.jp/1000ch/8906/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer"><img alt="2" src="/wp-content/uploads/2014/07/gmail.png" width="207" height="156" class="alignleft size-full"></a>
<strong><a href="https://html5experts.jp/1000ch/8906/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">Web Componentsが変えるWeb開発の未来</a></strong><br>
── <a href="https://html5experts.jp/1000ch/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">泉水翔吾</a></p>

<p><br><br></p>

<p><strong>＜5位＞</strong><br>
<a href="https://html5experts.jp/amurachi/10569/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer"><img alt="2" src="/wp-content/uploads/2014/09/talk1.jpg" width="207" height="156" class="alignleft size-full"></a>
<strong><a href="https://html5experts.jp/amurachi/10569/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">HTML5とかモバイルとかJSフレームワークとか、ぶっちゃけどうなの座談会</a></strong><br>
── <a href="https://html5experts.jp/amurachi/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">村地彰</a></p>

<p><br><br></p>

<p><strong>＜6位＞</strong><br>
<a href="https://html5experts.jp/yomotsu/5225/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer"><img alt="2" src="/wp-content/uploads/2014/02/1.png" width="207" height="156" class="alignleft size-full"></a>
<strong><a href="https://html5experts.jp/yomotsu/5225/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">初心者でも絶対わかる、WebGLプログラミング＜three.js最初の一歩＞</a></strong><br>
── <a href="https://html5experts.jp/yomotsu/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">小山田 晃浩</a></p>

<p><br><br></p>

<p><strong>＜7位＞</strong><br>
<a href="https://html5experts.jp/albatrosary/10855/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer"><img alt="2" src="/wp-content/uploads/2014/09/DSC074061.jpg" width="207" height="156" class="alignleft size-full"></a>
<strong><a href="https://html5experts.jp/albatrosary/10855/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">いまや最も優れたJavaScriptフレームワーク「AngularJSリファレンス」出版記念会</a></strong><br>
── <a href="https://html5experts.jp/albatrosary/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">佐川 夫美雄</a></p>

<p><br><br></p>

<p><strong>＜8位＞</strong><br>
<a href="https://html5experts.jp/girlie_mac/4558/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer"><img alt="2" src="/wp-content/uploads/2014/01/luminosity-devices.jpg" width="207" height="156" class="alignleft size-full"></a>
<strong><a href="https://html5experts.jp/girlie_mac/4558/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">HTML5で実現できる！環境光に合わせたレスポンシブなUI</a></strong><br>
── <a href="https://html5experts.jp/girlie_mac/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">Tomomi Imura</a></p>

<p><br><br></p>

<p><strong>＜9位＞</strong><br>
<a href="https://html5experts.jp/shumpei-shiraishi/11315/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer"><img alt="2" src="/wp-content/uploads/2014/11/ux2.jpg" width="207" height="156" class="alignleft size-full"></a>
<strong><a href="https://html5experts.jp/shumpei-shiraishi/11315/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">いま、UXを語るのはなぜ悩ましいのか？─長谷川恭久ロングインタビュー</a></strong><br>
── <a href="https://html5experts.jp/shumpei-shiraishi/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">白石 俊平</a></p>

<p><br><br></p>

<p><strong>＜10位＞</strong><br>
<a href="https://html5experts.jp/msakamaki/9486/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer"><img alt="2" src="/wp-content/uploads/2014/08/2a88bcbe7f516dcefdfd2218cea0988b.png" width="207" height="156" class="alignleft size-full"></a>
<strong><a href="https://html5experts.jp/msakamaki/9486/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">エンタープライズで使える！実践から学ぶJavaScript MVCフレームワークの選び方</a></strong><br>
── <a href="https://html5experts.jp/msakamaki/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">酒巻瑞穂</a></p>

<p><br><br></p>

<p><strong>＜11位＞</strong><br>
<a href="https://html5experts.jp/iwase/7172/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer"><img alt="2" src="/wp-content/uploads/2014/06/20140604_decode_prezen_IMG_0270.jpg" width="207" height="156" class="alignleft size-full"></a>
<strong><a href="https://html5experts.jp/iwase/7172/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">Web技術者も知るべきデモ・プレゼンの極意（西脇資哲氏）「Microsoft de:code」イベントレポート</a></strong><br>
── <a href="https://html5experts.jp/iwase/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">岩瀬 義昌</a></p>

<p><br><br></p>

<p><strong>＜12位＞</strong><br>
<a href="https://html5experts.jp/furoshiki/9136/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer"><img alt="2" src="/wp-content/uploads/2014/08/d6940b0c38258d9311986c932cbe9406.png" width="207" height="156" class="alignleft size-full"></a>
<strong><a href="https://html5experts.jp/furoshiki/9136/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">HTML5が変える、エンタープライズITの可能性とこれから</a></strong><br>
── <a href="https://html5experts.jp/furoshiki/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">川田寛</a></p>

<p><br><br></p>

<p><strong>＜13位＞</strong><br>
<a href="https://html5experts.jp/iwase/7369/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer"><img alt="2" src="/wp-content/uploads/2014/06/10453028_750539778322094_4305687654356604239_o.jpg" width="207" height="156" class="alignleft size-full"></a>
<strong><a href="https://html5experts.jp/iwase/7369/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">【速報】Google I/O 2014 キーノート ライブレポート </a></strong><br>
── <a href="https://html5experts.jp/iwase/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">岩瀬 義昌</a></p>

<p><br><br><br></p>

<p><strong>＜14位＞</strong><br>
<a href="https://html5experts.jp/t32k/5743/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer"><img alt="2" src="/wp-content/uploads/2014/03/687474703a2f2f692e696d6775722e636f6d2f38316b4b6e78482e706e67.png" width="207" height="156" class="alignleft size-full"></a>
<strong><a href="https://html5experts.jp/t32k/5743/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">自分の書いたコードが即座に解析できる「StyleStats」でCSSを測ろう！</a></strong><br>
── <a href="https://html5experts.jp/t32k/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">石本 光司</a></p>

<p><br><br></p>

<p><strong>＜15位＞</strong><br>
<a href="https://html5experts.jp/canidoweb/7359/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer"><img alt="2" src="/wp-content/uploads/2014/06/ionic1.png" width="207" height="156" class="alignleft size-full"></a>
<strong><a href="https://html5experts.jp/canidoweb/7359/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">キミはionicを知っているか？AngularJS+PhoneGap+美麗コンポーネント群！</a></strong><br>
── <a href="https://html5experts.jp/canidoweb/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">金井 健一</a></p>

<p><br><br></p>

<p><strong>＜16位＞</strong><br>
<a href="https://html5experts.jp/ahomu/9307/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer"><img alt="2" src="/wp-content/uploads/2014/07/14803538523_b7b20a90bd_z.jpg" width="207" height="156" class="alignleft size-full"></a>
<strong><a href="https://html5experts.jp/ahomu/9307/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">話題のMaterial DesignをWebで実現！Polymerで「Paper Elements」を試そう</a></strong><br>
── <a href="https://html5experts.jp/ahomu/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">佐藤歩</a></p>

<p><br><br></p>

<p><strong>＜17位＞</strong><br>
<a href="https://html5experts.jp/anatoo/7253/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer"><img alt="2" src="/wp-content/uploads/2014/06/hybrid_app_structure1.png" width="207" height="156" class="alignleft size-full"></a>
<strong><a href="https://html5experts.jp/anatoo/7253/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">HTML5ハイブリッドアプリ開発、最新動向はやわかり！</a></strong><br>
── <a href="https://html5experts.jp/anatoo/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">久保田 光則</a></p>

<p><br><br></p>

<p><strong>＜18位＞</strong><br>
<a href="https://html5experts.jp/shumpei-shiraishi/11532/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer"><img alt="2" src="/wp-content/uploads/2014/11/kidachi8.jpg" width="207" height="156" class="alignleft size-full"></a>
<strong><a href="https://html5experts.jp/shumpei-shiraishi/11532/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">ミツエーリンクスのCTOに「UXとWebアクセシビリティ」について聞いてきた─木達一仁ロングインタビュー</a></strong><br>
── <a href="https://html5experts.jp/shumpei-shiraishi/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">白石 俊平</a></p>

<p><br><br></p>

<p><strong>＜19位＞</strong><br>
<a href="https://html5experts.jp/1000ch/11142/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer"><img alt="2" src="/wp-content/uploads/2014/10/devtools-shadowdom.png" width="207" height="156" class="alignleft size-full"></a>
<strong><a href="https://html5experts.jp/1000ch/11142/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">Web Componentsを構成する4つの仕様 ー Web Components基礎編</a></strong><br>
── <a href="https://html5experts.jp/1000ch/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">泉水翔吾</a></p>

<p><br><br><br></p>

<p><strong>＜20位＞</strong><br>
<a href="https://html5experts.jp/toshirot/4595/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer"><img alt="2" src="/wp-content/uploads/2014/01/8__.jpg" width="207" height="156" class="alignleft size-full"></a>
<strong><a href="https://html5experts.jp/toshirot/4595/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">NUCで手のひらサイズの格安WebSocketサーバーを立ててみた(ハード組立編)</a></strong><br>
── <a href="https://html5experts.jp/toshirot/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">高橋 登史朗</a></p>

<p><br><br><br><br></p>

<h2>モバイルWeb、WebComponets、AngularJS…</h2>

<p>モバイルWebというキーワードは今年注目を集めましたね。関連記事がいくつかランクインしています。また、WebComponets、AngularJSという今年話題になった技術の記事もランクインしています。特集では、GoogleI/O特集やExperts Opinions「UX」特集が注目を集めました。UX特集は年明けにも記事公開を予定していますので、お楽しみに！</p>

<p>HTML5 Experts.jpは2014年も多くの方々にご愛読いただきまして、執筆陣・編集部共々感謝しています。ありがとうございました。来年も引き続き宜しくお願いいたします。</p>
]]></content:encoded>
			</item>
	</channel>
</rss>
