2016.10.09 DevFest Tokyo 2016
Web アプリケーション開発を専門とするソフトウェアエンジニア。企業で働く傍ら、技術顧問として複数企業のエンジニアリングに関わり、高品質で維持しやすい Web アプリケーションを作るための活動を続けている。
長らく Web 開発者が向き合ってきた
(╯°□°)╯︵ SSƆ— 1000ch (@1000ch) 2016年7月11日
(╯°□°)╯︵ SSƆ
CSS はつらい。本当につらい。
これまでのものを v0、新たなものを v1 として、改めて仕様の策定が進んでいる
createShadowRoot()
attachShadow()
Shadow Root
<content>
<slot>
const div = document.querySelector('div'); const shadowRoot = div.attachShadow({ mode: 'open' // or 'close' }); // readonly な shadowRoot プロパティの追加 console.log(div.shadowRoot);
引数に open か close かどうかを指定する(必須)
外部からアクセスできる Shadow DOM と、アクセスできない Shadow DOM。 Closed Shadow DOM であれば shadowRoot プロパティは null を返す
shadowRoot
null
Though multiple shadow roots were originally introduced to support an Inheritance Model for components, Blink has already deprecated this feature even in v0. Do not use multiple shadow roots.
ある要素の attachShadow() を2回以上実行すると例外が発生する
article, aside, blockquote, body, div, footer, h1, h2, h3, h4, h5, h6, header, nav, p, section, span
article
aside
blockquote
body
div
footer
h1
h2
h3
h4
h5
h6
header
nav
p
section
span
<content> で指定していた Insertion Points は、 <slot> に代わり Slots と表現されるようになる。セレクタで指定していたのが、 <slot name=slot-name> のようなスロット名の完全一致で挿入される。
<slot name=slot-name>
<content
<template> <style> ::content input { background: skyblue; } </style> <div> <content select=".class-name"></content> <content></content> </div> </template> <form-container> <input class="class-name" type="text"> <button>Button</button> </form-container>
<template> <style> ::slotted(input) { background: skyblue; } </style> <div> <slot name="slot-name"></slot> <slot></slot> </div> </template> <form-container> <input slot="slot-name" type="text"> <button>Button</button> </form-container>
更なる詳細はこちらの資料を参照のこと
document.registerElement
window.customElements
<script> const FooElement = Object.create(HTMLElement.prototype); FooElement.createdCallback = () => { ... }; FooElement.attachedCallback = () => { ... }; FooElement.detachedCallback = () => { ... }; FooElement.attributeChangedCallback = () => { ... }; document.registerElement('foo-element', { prototype: FooElement }); </script>
<script> class FooElement extends HTMLElement { constructor() { ... } connectedCallback() { ... } disconnectedCallback() { ... } attributeChangedCallback() { ... } adoptedCallback() { ... } } window.customElements.define('foo-element', FooElement); </script>
// <foo-element> コンストラクタの参照 const FooElement = customElements.get('foo-element'); // <foo-element> が定義されたタイミング customElements.whenDefined('foo-element').then(() => { console.log('foo-element is defined'); });
不完全な状態でページが表示されるのを避けるには、 :defined 擬似クラスだけでは難しい
:defined
Issue #427 · w3c/webcomponents
is
今のところ WebKit は <button is="foo-button" /> のような Custom Elements によるネイティブ要素の拡張をしない方針を示している
<button is="foo-button" />
Mozilla は ES6 Modules を意識して見送っている。The state of Web Components でも触れているように、ES Modules で解決することを支持している
iOS 10 のシェア次第だが、時間の問題
メニューの Develop → Experimental Features → Custom Elements
みんなで Shadow DOM (unprefixed) と Custom Elements に投票しよう!
Polymer 2.0 is just starting to come together. For a very early look at what's coming, check out: https://t.co/w6U7L4I0OZ— Polymer (@polymer) 2016年9月9日
Polymer 2.0 is just starting to come together. For a very early look at what's coming, check out: https://t.co/w6U7L4I0OZ
Polymer/polymer リポジトリの 2.0-preview ブランチ
2.0-preview
Polymer 2.0 Preview が公開されていますが、その時のアナウンス内容を日本語訳してみました。興味のある方はぜひお読みください。 https://t.co/Y9EEERPKCR #polymer #html5j— Yoichiro Tanaka (@yoichiro) 2016年9月24日
Polymer 2.0 Preview が公開されていますが、その時のアナウンス内容を日本語訳してみました。興味のある方はぜひお読みください。 https://t.co/Y9EEERPKCR #polymer #html5j
Polymer Summit 2016 registration is now open! Join us in London on October 17-18. https://t.co/gWSEOpy3Sb pic.twitter.com/Noj4kAsdqd— Polymer (@polymer) 2016年8月15日
Polymer Summit 2016 registration is now open! Join us in London on October 17-18. https://t.co/gWSEOpy3Sb pic.twitter.com/Noj4kAsdqd
Polymer Summit 2016 in London on October 17-18
v1.x
const MyElement = Polymer({ is: 'my-element', created: function () {}, attached: function() {}, detached: function() {}, attributeChanged: function() {}, ready: function() {} });
class MyElement extends Polymer.Element { static get is() { return 'my-element'; } static get config() { return { /* properties, observers meta data */ }; } constructor() { super(); } connectedCallback() { super.connectedCallback(); } } customElements.define(MyElement.is, MyElement);
polymer.html が引き続き提供され、Polymer.dom() や Polymer.CompatElement といった Polymer v1.x で提供されてきた API も含まれる
polymer.html
Polymer.dom()
Polymer.CompatElement
Polymer で抽象化してきた API が排除されネイティブの API を使うように。例えば、Shady DOM v1 が提供されることで DOM 操作に関しても Polymer.dom() が不要になる
is=""
Polymer v1.x の機能は引き続き提供されるが、Type Extension (is="...") の雲行きが怪しいので…
is="..."
<dom-repeat items="{{items}}"> <template>...</template> </dom-repeat> <custom-style> <style>...</style> </custom-style>
故に、サポートされていない環境で使うには webcomponentsjs によるポリフィルが必要である。そして新たなスペックに対応するポリフィルを提供する v1 ブランチの開発が進められている
v2 のリリースに伴いアップデートされるが、使う側に影響はない(はず)
$ bower install --save Polymer/polymer#2.0-preview