HTML Importsでインポート先に引き継がれる内容
Published at 2014-10-07
https://github.com/pazguille/github-card/blob/master/webcomponent/github-card.html これってなんで
doc.registerElement
になってるんだろう・・
っていう質問をされたので調べたメモ。内容的にはHTML ImportsするHTMLのコンテキストになるdocumentの続きにあたるかも。
registerElementの実行者とカスタム要素の登録先
以下の様なカスタム要素を作成し、ロードする場合を考える。
sample-element.html
<script>
var doc = document.currentScript.ownerDocument;
doc.variable = 'this is the variable in sample-element.html';
window.SampleElement = document.registerElement('sample-element', {
prototype: Object.create(HTMLElement.prototype)
});
</script>
loader.html
<html>
<head>
<meta charset="utf-8">
<link rel="import" href="sample-element.html">
</head>
<body>
<sample-element>Sample</sample-element>
</body>
</html>
document.currentScript.ownerDocument
をdoc
にキャッシュしないと、sample-element.html
内に書いた要素を取得する時に困る話は前述のエントリでしてある。
document.registerElement('sample-element', {});
しているのは、sample-element.html
をインポートするHTMLのdocument
になる。
でも<github-card>
ではこの例で言うところのsample-element.html
のdocument
でregisterElement()
を実行している。
感覚的に言えばインポートする側のdocument
で登録を実行するほうがしっくりくるんだけどそうでもないんだろうか。
HTML Importsでカスタム要素の定義もインポートされる
感覚の話はさておき、<github-card>
を見る限りregisterElement()
したカスタム要素は引き継がれるよう。
sample-element.html
でわざとらしく宣言したvariable
という変数も見てみる。引き継がれないだろうけど、一応。
当然のごとくvariable
はdoc
にしかない。が、document.createElement('sample-element')
は両方とも成功している。
Firefox Nightly 35.0a1でも試してみた。
インポートしているsample-element.html
内で宣言しているdoc
がundefined
になってしまっているんだけど、doc
に登録している<sample-element>
はちゃんとインポート先のdocument
に登録されていた。
スタイルシートも引き継がれる
sample-element.html
内でsample-element.css
をロードし、そのsample-element.html
をインポートするとインポート先でsample-element.css
で定義しているクラスは利用出来る。
このとき、sample-element.css
はdoc.styleSheets
にぶら下がっているけど、当然document.styleSheets
には属さない。
HTML ImportsとCustom Elementsの仕様を見てみる
HTML Importはこんな感じでlink関係をツリー上に持つらしい。で、このHTML Importsのツリーは
The import tree order of a given custom element of an import tree is determined by tree order in an import tree that was flattened by replacing every import link with the content of its imported document.
インポートしてくるドキュメントでリプレイスされ、ドキュメント達は構造上並列になる(と書いてあるように見える)。
Element registration is a process of adding an element definition to a registry. One element definition can only be registered with one registry.
ひとつのドキュメントにつき、ひとつのレジストリが存在し、要素の定義はそのレジストリに定義される。
色々読み漁ったけど、英語力足りなすぎて直接言及している場所がどこかわからなかった。かろうじて、
When creating an import, use the registry of the master document.
先程のスタイルシートの挙動から察するに、 HTML Importsのツリー上の子孫にいるカスタム要素のレジストリは親から参照出来る ってことなんだと思うが、HTML Importが発生した時点でインポート先のドキュメントにカスタム要素の宣言がマージされることを意味しているような気も。
詳しい人おしえて下さい。