GitHubの草を草色に戻すChrome拡張作った

GitHubのデザインが色々変わって、草が草の色じゃなくなったのが寂しかったので、草色にするChrome拡張を作りました。

2020/06/29 追記
[ストア](https://chrome.google.com/webstore/detail/githubkusachange/cgjbfifnnpcfigdbfknooafhjkliidhg) に並びました。良かったらインストールして使ってみてください。

## 効果

### before（新デザイン）

<img width="809" alt="スクリーンショット 2020-06-24 22.28.56.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/32169/1c9b53bd-290c-9817-61ec-cd4689eb47fe.png">


### after（Chrome拡張を実行）

<img width="791" alt="スクリーンショット 2020-06-24 22.29.03.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/32169/301474ee-4add-0e44-d92c-1777c8d49d84.png">

どうですか？草ですね。落ち着きますね。


## 入手方法

2020/06/29 追記
[ストア](https://chrome.google.com/webstore/detail/githubkusachange/cgjbfifnnpcfigdbfknooafhjkliidhg) に並びました。

以下はローカルでビルドする場合の手順です。

リポジトリは[こちら](https://github.com/daisuke-fukuda/github-kusa-change)です。

### ビルド方法

READMEに書きましたが、

```bash
cd extension
npm install
npm build
```

して、手動で拡張機能を[インストール](https://qiita.com/k__watanabe/items/4777ecf1242927768b53#03300459chrome%E3%81%AB%E6%8B%A1%E5%BC%B5%E6%A9%9F%E8%83%BD%E3%82%92%E8%AA%AD%E3%81%BF%E8%BE%BC%E3%81%BE%E3%81%9B%E3%82%8B)してください。


## 実行方法




草のページを開いたら、ツールバーの草アイコン（↓のやつ）をクリックしてください。
![icon-48.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/32169/a26d0131-d49d-7c9d-2b00-6c20d05a131e.png)

本当はページ開いたら自動で実行されるようにしたいですが、未対応です。


## 実装の解説（ver1）

2020/06/29追記 これを書いた後に数日経って確認したら、cssのみで無理やり書き換える実装から、素直な実装に変更されていました。ver2を追記しています。


### 草本体

GitHubの草はSVGで実装されています。SVGはHTMLのDOMと同じように、JavaScriptでごりごり変更する事が可能です。

図で示しているのは、1個の草（1日の草？）です。ぱっと見、fillで入っている値が、新しい値になったのかと思いきや、この値は昔のスタイル（草色）のスタイルのままです。
scss（要はcss）で旧スタイルの色から、新スタイルの色に変換するclassを適用する事で、結構無理やり色を変えています。
<img width="513" alt="daisuke-fukuda.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/32169/08be1c41-1c09-8eae-1afc-bebfbac399f6.png">

なので、色を変更する処理としては、

```JavaScript
  // attributesのfillは昔のcolorがそのまま入っていて、
  // 新旧のcolorをmappingしたscssで色が変わっている
  // なので、styleでcolorを設定してあげればscssより優先されるので元の色に戻る
  const fill = kusa.getAttribute('fill');
  kusa.style.fill = fill;
```
という風に、`fill` の値をstyleに設定してあげれば昔の色になります。
（classよりstyleで直書きの方が強いので）


### legend

legendはここの見本の事です。class名がlegendってなってたのですが、そういう意味あるんですかね？？

<img width="175" alt="スクリーンショット 2020-06-24 22.52.23.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/32169/0b50460e-d940-ffc2-b6c4-2f98bcfbf9e1.png">

で、ここはSVGではなくて、ulとliで実装されています。

styleとして直書きされている方には昔の色がそのまま入っていて、scss（css）で`!important` で色を上書きしています。
優先度で言うと、
style（!important無し） <  css（!import付き）
だからです。

<img width="298" alt="daisuke-fukuda2.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/32169/ad580d6a-f717-ff43-18cc-7a19b2ee6512.png">

なので、色を変更するには

```JavaScript
  // styleで元々の色が入っているのを、cssで!importandで無理やり新しい色にしている
  // ので、元のstyleを !importantにしてあげれば、cssより優先されて元の色になる、
  const color = legend.style.backgroundColor;
  legend.style.setProperty('background-color', color, 'important');
```

元のstyle（昔の色が入っている）に `!important` をつけてあげれば、
style（!important有り） >  css（!import付き）
なので昔の色に戻ります。

### なんでこんな面倒な事になってるのか考察

おそらく、元の処理にはできるだけ手を加えずに、cssの変更だけで対応する作戦をとっているためと思われます。

CSSの変更だけなので、影響範囲を見た目だけに抑えて予期せぬ挙動の変更（ボタンが隠れて押せなくなるとかは考えられますが、、）が起きないようにしたり、チームのリソースの配分の都合等が考えられます。

まあ、↑で確認した通り、styleがかなり汚れるのでできれば避けた方が良いと私は思いますが、、、


## 実行方法（ver2）2020/06/29追記

素直な実装になっていたので、修正しました。おそらくver1に該当する無理やり実装は、移行期間だったのだと思われます。


### 草本体

<img width="508" alt="daisuke-fukuda3.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/32169/36776cc9-c9c7-dbd7-da09-dab310d46d0c.png">

ver1とは違い、svgのfill要素に素直に新しい色（エメラルドグリーン）の色が設定されていますので、シンプルに草色に置き換えてあげればOKです。

```javascript
const colorMap = {
  '#ebedf0': '#ebedf0',
  '#9be9a8': '#cbe295',
  '#40c463': '#89c578',
  '#30a14e': '#439647',
  '#216e39': '#2b5e2d',
};


const changeKusaColor = (kusa) => {
  const fill = kusa.getAttribute('fill');
  kusa.style.fill = colorMap[fill];

  // 丸みを帯びたデザインも打ち消し
  kusa.style.width = '11px';
  kusa.style.height = '11px';
  kusa.style.rx = '0';
  kusa.style.ry = '0';
};
```

### legend

legendも同様で、素直にbackground-colorで定義されているので、シンプルに置き換えます。

<img width="517" alt="daisuke-fukuda4.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/32169/81ec7115-f20d-f49f-6354-283f7cec57ae.png">

```javascript
const colorMap = {
  '#ebedf0': '#ebedf0',
  '#9be9a8': '#cbe295',
  '#40c463': '#89c578',
  '#30a14e': '#439647',
  '#216e39': '#2b5e2d',
};

// https://decks.hatenadiary.org/entry/20100907/1283843862
const rgbTo16 = (col) => `#${col.match(/\d+/g).map((a) => (`0${parseInt(a).toString(16)}`).slice(-2)).join('')}`;

const changeLengendColor = (legend) => {
  const color = legend.style.backgroundColor;
  console.log(color);
  legend.style.setProperty('background-color', colorMap[rgbTo16(color)]);

  // 丸みを帯びたデザインも打ち消し
  legend.style.width = '11px';
  legend.style.height = '11px';
  legend.style.borderRadius = '0';
};

```
取得した `backgroundColor` は `rgb(48, 161, 78)` みたいなrgb形式になっていたので、hex形式に変換しています。


## まとめ

数時間で適当に作ったものなので色々荒いのですが、とりあえず動くので個人的には満足しています。（草色落ち着く、、、）

あと、GitHubがどうやって今回の見た目変更を実装したかが確認できたのも良かったです。きっと色々大変なんでしょうね、、

2020/06/29追記

たまたま変更を追っかけていたので、cssのみで見た目変更 -> 本体を修正 というフローが確認できました。見た目上は変更されてないですが、裏で行っていたリリース方法が確認できて勉強になりました。