Electron製のアプリケーションにスタイルシートを埋め込む


Hangoutなど、公式のアプリがないWebサービスはnativefierを使ってスタンドアロンのアプリとして使っています。

画面の大きさが狭いとか、標準のCSSをカスタマイズしたくなったので備忘録として記録しておきます。

nativefierについてはこちらの記事が参考になります。

※ 今回はMacを対象にしていますが

Electron製のアプリケーションの中身

自作したHangout.appを開いてみるとこんな感じの構成になっています。Macの普通のアプリと同じで特に変わったものはありません。

  • /Contents
    • /Frameworks
    • /MacOS
    • /Resources
    • /app ※
    • Info.plist
    • PkgInfo

Electronの起動などに使われるJavaScriptは/appディレクトリに入っています。

書き換え対象のJS

Electronは起動すると/lib/main.jsを起動します。その中で/lib/static/preload.jsを読み込んでブラウザを起動するような仕組みになっています。

preload.jsは

に書いたJavaScriptのようなものなので、一番最初に読み込まれます。

preload.jsの修正

inject用のディレクトリが/app/injectに用意されているので、そこにinject.cssを設置して読み込む形式とします。

CSSをinjectする関数injectStylesheet()を定義して、DOMContentLoadedの後ろで呼び出すのがわかりやすいと思います。

元々JavaScriptを読み込むためのinjectScripts()が定義されているのでそちらに合わせる形で作っています。

function injectStylesheet(){

}

document.addEventListener('DOMContentLoaded', function () {
  //中略
  injectScripts();
  injectStylesheet(); //<- CSSの読み込みを行う
});

injectStylesheet()の実装

Electron製のアプリは内部でChromiumが使われています。そのため、制限として、ローカルのファイルをそのまま<link>で読み込むことが出来ません。

今回はCSSファイルを読み込んで、<style>タグで埋め込むことにしました。
そのために必要なパッケージは既にpreload.jsで定義されているので、特に追加する必要はありません。

function injectStylesheet(){
  var styleSheet = _path2.default.join(__dirname, '../../', 'inject/inject.css');

  //cssを読み込む
  _fs.readFile(styleSheet, 'utf8', function (err, text) {

    var styleNode = document.createElement("style");
    styleNode.setAttribute("type","text/css")

    var content = document.createTextNode(text)
    styleNode.append(content)
    document.getElementsByTagName("head")[0].append(styleNode)

  });
}

injectStylesheet()では下記の流れで処理します。

  1. _path2.default.join()を使ってCSSのパスを変換する
  2. _fsを使ってCSSのファイルを読み込む
  3. <style>タグを作る