Slack for Windowsで中華フォントになる現象を直す

# 背景
[@hnle0 氏がせっかく直してくれた](https://blog.hinaloe.net/2015/03/24/change-font-of-slack-for-windows/)のにまた中華フォントになる不具合が発生したので調べてみた．
ついでにファイルに対するコメントが元々中華フォントだった現象も直した．
[2015/12/14追記]
パッチも作った．一部のコマンドを修正した．
[2015/12/15追記]
一部のテキストが中華フォントのままだったので，パッチをアップデートした．
もし以前のパッチを適用してしまった場合は，バックアップから復元するか，[ここ](https://www.dropbox.com/s/mpf12li0wxxn0qn/slack-1.2.7-meiryo-v1.git-patch?dl=0)から再度ダウンロードし，

```bat
git apply -R slack-1.2.7-meiryo-v1.git-patch
```
をすれば良い．

# 原因
## その１
cssで指定されているフォントが変わっていてreplaceされていなかった．

## その２
その１が原因なのかはわからないが，日本語キーボードの場合にフォントを直す部分がコメントアウトされていた．

# 直し方
基本的には上のブログ記事と同じようなことをする．

## パッチで適用する場合
[ここ](https://www.dropbox.com/s/am3fd1v864jlm4r/slack-1.2.7-meiryo-v4.git-patch?dl=0)のパッチをダウンロードし，

```bat
cd %LOCALAPPDATA%\slack
copy app-1.2.7\resources\app.asar app-1.2.7\resources\app.asar.bak
git apply slack-1.2.7-meiryo-v4.git-patch
```
をすれば良い．

```bat
git apply -R slack-1.2.7-meiryo-v4.git-patch
```
で戻せるはずだが，一応念のため上に書いたように先にバックアップを取っておくことを推奨する．
v1.2.7のみの対応になるので，もしv1.2.8(?)以降でも治っていなかった場合は以下の手動で直す方法を推奨する．

## 手動で直す場合
何やってるのか知らないと怖いという方もいらっしゃると思うので，以下に手動での直し方を記す．

### 1. 必要なものをインストール
* Node.jsをインストールしていなければ，インストールする．インストール方法はここでは解説しない．
* asar, electron-compileをインストールする．
 
```
npm install -g asar
npm install --save -g electron-compile
npm install --save-dev -g electron-compilers
```

### 2. 展開
asarファイルを展開する．Slackのバージョン名は変わると思うので，適宜変更のこと．バックアップも取っておく．

```bat
cd %LOCALAPPDATA%\slack\app-1.2.7\resources
copy app.asar app.asar.bak
asar e app.asar app
```

### 3. 書き換え
`app.extract\src\ssb\app.js`を書き換える．

```diff
--- a/app-1.2.7/resources/app/src/ssb/app.js    2015-12-15 05:09:44.568023700 +0900
+++ b/app-1.2.7/resources/app/src/ssb/app.js      2015-12-15 05:06:49.781343500 +0900
@@ -35,7 +35,7 @@
   didFinishLoading() {
     ipc.sendToHost('didFinishLoading');

-    //this.fixJapaneseFontFallbacks();
+    this.fixJapaneseFontFallbacks();
     this.checkForBetaReleaseChannel();

     try {
@@ -218,18 +218,40 @@
     // Replace the Font styles for these selectors with one that adds Meiryo
     // as a fallback. We don't do this in the webapp because if we did, it would
     // fuck up people reading Chinese text.
-    this.fixStyleMatchingAttribute('class', 'message', ".message");
-    this.fixStyleMatchingAttribute('id', 'message-input', "#message-input");
-    this.fixStyleMatchingAttribute('class', 'file_name', ".file_name");
-  }
-
-  fixStyleMatchingAttribute(attributeName, attributeValue, selector) {
-    let span = document.createElement('span');
-    span.setAttribute(attributeName, attributeValue);
+    this.fixStyleMatchingAttribute('span', 'class', 'message', ".message");
+    this.fixStyleMatchingAttribute('textarea', 'id', 'message-input', "#message-input");
+    this.fixStyleMatchingAttribute('span', 'class', 'file_name', ".file_name");
+    this.fixStyleMatchingAttribute('span', 'class', 'comment', ".comment");
+    this.fixStyleMatchingAttribute('span', 'class', 'modal', ".modal");
+    this.fixStyleMatchingAttribute('span', 'id', 'details_tab', "#details_tab");
+    this.fixStyleMatchingAttribute('textarea', null, null, "input[type=url], input[type=text], input[type=tel], input[type=number], input[type=email], input[type=password], select, textarea");
+    this.fixStyleMatchingAttribute('h4', null, null, "h1, h2, h3, h4");
+    this.fixStyleMatchingAttribute('span', 'id', 'end_display_meta', "#msgs_scroller_div #end_display_div #end_display_meta");
+    this.fixStyleMatchingAttribute('span', 'id', 'loading_welcome_msg', "#loading_welcome_msg");
+    this.fixStyleMatchingAttributeMonospace('span', 'class', 'monospace', '.monospace');
+    this.fixStyleMatchingAttributeMonospace('pre', null, null, 'code, pre');
+    this.fixStyleMatchingAttributeMonospace('span', "class", "CodeMirror", '.CodeMirror');
+  }
+
+  fixStyleMatchingAttribute(tagName, attributeName, attributeValue, selector) {
+    let span = document.createElement(tagName);
+    if(attributeName)
+      span.setAttribute(attributeName, attributeValue);
     document.body.appendChild(span);
     let cssom = window.getComputedStyle(span);
+    let fontFamily = "Meiryo, 'MS PGothic', " + cssom.fontFamily;
+    document.body.removeChild(span);

-    let fontFamily = cssom.fontFamily.replace("'Lato'", 'Lato').replace("Lato,", "Lato, Meiryo, MS PGothic,");
+    let style = document.createElement('style');
+    style.innerText = `${selector} { font-family: ${fontFamily} !important }`;
+    document.head.appendChild(style);
+  }
+
+  fixStyleMatchingAttributeMonospace(tagName, attributeName, attributeValue, selector) {
+    let span = document.createElement(tagName);
+    if(attributeName)
+      span.setAttribute(attributeName, attributeValue);
+    document.body.appendChild(span);
+    let cssom = window.getComputedStyle(span);
+    let fontFamily = "'MS Gothic', " + cssom.fontFamily;
     document.body.removeChild(span);

     let style = document.createElement('style');
```

### 4. electron-compileをする
現在のSlackはES6準拠で書かれているため，一度コンパイルしてあげないといけない．そのため先ほどインストールしたelectron-compileを用いてコンパイルを行う．

```bat
electron-compile -t .\app\cache .\app
```
ここでもし，`ReferenceError: Symbol is not defined`のようなのが出る場合，Node.jsのバージョンが古いと思われるので，アップデートする．

### 5. asarで固める
```bat
asar p app app.asar --unpack-dir static --unpack {*.node,*.dll}
```

### 6. 再起動
もしSlackが立ち上がっていたら，終了して再起動をする．