作ったのはbackground.jsからexecuteScriptで表示中のタブにウィジェットコードを注入するchrome拡張。 キーワードはこんな感じ。
- es6: 2017年だけれども。
- riotjs: reactより簡単、軽量。
- shadowDom: スタイルのカプセル化でreset.cssいらず。
- yarn: ものは試しに速いと噂の。
- gulp: タグコンパイルもbabelもwebpackもgulpタスクで。
以下、ハマりどころと対処法。vivaパワープレイ。
style-loaderがshadowDOMに非対応
style-loaderを使ってshadow-root内に直接スタイルを流し込めない。
一旦head
にスタイルを流しこんでから、Shadow DOMスコープへstyle
を移動させてなんとかした。
require('style-loader!css-loader!./shadow.css'); let style = document.querySelectorAll('head style').pop(); let shadow = document.querySelector('#app-container').attachShadow({mode: 'open'}); document.head.removeChild(style); shadow.appendChild(style);
@font-faceがShadow DOMスコープで動作しない
Shadow DOMスコープ内では@font-face
は使えないようだ。
スタイルを分割して@font-faceの部分をShadow DOMスコープ外へ移動させた。
<head> <style type="text/css"> @font-face { font-family: "Beautiful Font"; src: url(data:application/font-woff2;base64,...); } </style> </head> <body> ... <div id="app-container"> #shadow-root (open) <style type="text/css"> .beauty { font-family: "Beautiful Font"; } </style> <p class="beauty">Beautiful!</p>
riotタグのスタイルはheadに追加される
tagファイルに記述したスタイルはheadに差し込まれるので、Shadow DOMスコープ内に反映できない。
::shadow
と/deep/
は廃止されたため、カスタムタグへ書いていたスタイルをShadowDOMへ注入するスタイルシートへ移動させた。
riotタグのonclickがDOMエレメントのonclickハンドラに登録される
カスタムタグに記述したonclick={foovar}
がそのままDOMエレメントのonclick
ハンドラにセットされてHTMLElement.onclick = {foobar}
な状態になった。
クリックすると当然エラー出力。
ただ、riotでaddEventHandlerもされているようで、動くことは動く。
extension経由でなければ発生しないので、chrome側でごちゃごちゃやってるようだ。
結果的にはonclick
という属性名に反応してしまうようなのでriotjsへパッチを当てて回避。
- var EVENTS_PREFIX_REGEX = /^on/; + var EVENTS_PREFIX_REGEX = /^r-on/;
タグではonclick={foobar}
の代わりにr-onclick={foobar}
と書くようにする。
(実際にはpack済みのjsに対してgulpでreplace('/^on/', '/^r-on/')
するようにした)
riotjs@3.3.1, google-chrome@57(beta)