作ったのは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)
