【Chrome 拡張機能】ChromeのNew Tab Pageを自作してみる

# 概要

Chromeには様々な拡張機能が[Webストア](https://chrome.google.com/webstore?hl=ja)で公開されています。
New Tab Pageをカスタマイズできる拡張機能もたくさん公開されています。

- [Aewsome New Tab Page](https://chrome.google.com/webstore/detail/awesome-new-tab-page/mgmiemnjjchgkmgbeljfocdjjnpjnmcg)
- [Infinity 新しいタブ ](https://chrome.google.com/webstore/detail/infinity-new-tab-producti/dbfmnekepjoapopniengjbcpnbljalfg)

などなど便利な拡張機能がすでにたくさんあります。

しかし、自分好みのちょうどいいのがなく、自作してみると非常に簡単にできたので、記事にしようと思いました。
この記事を参考に自分専用のNew Tab Pageを作っちゃいましょう。


# 実装
## ディレクトリ構成

```
MyNewTabPage
├── index.html
└── manifest.json
```
必要なファイルは2つだけ。

### index.html
```html
<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>New Tab</title>
</head>

<body>
  <!-- コンテンツを記述 -->
</body>

</html>
```

得にNew Tab Page用の記述などはありません。

### manifest.json
```json
{
  "name": "my-new-tab-page",
  "manifest_version": 2,
  "description": "My new tab page.",
  "version": "0.0.1",
  "permissions" : ["management"],
  "chrome_url_overrides" : {
    "newtab": "index.html"
  }
}
```

ポイントはこの部分

```json
"chrome_url_overrides" : {
  "newtab": "index.html"
}
```

Chromeで```chrome://newtab``` へアクセスした場合に
```index.html``` を表示するようにします。

### JS / CSS

いつものWeb開発と変わりなくJSやCSSも問題なく使えます。
Ajaxなどの通信も可能です。


# New Tab Page への設定手順

1. Chromeで [chrome://extensions/](chrome://extensions/) にアクセス
2. 「デベロッパーモード」にチェックを入れる
3. 「パッケージ化されていない拡張機能を読み込む」をクリック
4. 今回実装したディレクトリを選択する

以上の手順で拡張機能が有効になります。
この作業でディレクトリの設定ができたので、該当ディレクトリを編集してNew Tab Pageをリロードすると、反映されます。

# Chromeのアプリを表示する

Chromeのアプリを取得できるように[chrome.management API](https://developer.chrome.com/extensions/management) が提供されています。
chrome.management API はChromeのNew Tab Page でのみ使用できるため、
```index.html``` を直接Chromeで開いてる場合などでは使用できません。
動作確認は実際にNew Tab Pageで確認しましょう。

アプリ一覧を取得するには```getAll``` メソッドを使用します。

```js
chrome.management.getAll(apps => {
  console.log(apps);
});
```

<img width="391" alt="スクリーンショット 2019-04-21 23.28.34.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/207520/59334a4c-e458-4817-0c95-e86f8e6cffcd.png">

これで、インストールしているすべての拡張機能一覧を取得することができます。

拡張機能はいくつか種類があります。
New Tab Pageで表示させたい拡張機能は、Chromeアプリのみです。
```getAll```メソッドで取得した情報には```isApp```というフラグが含まれています。
さらに```enabled```で拡張機能が有効か無効か判定できます。

拡張機能が有効なChromeアプリのみを取得します。

```js
chrome.management.getAll(apps => {
  apps.forEach(app => {
    if (app.enabled && app.isApp) {
      console.log(app);
    }
  });
});
```

<img width="399" alt="スクリーンショット 2019-04-21 23.37.17.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/207520/b58bc0a3-4e33-18b5-2817-f29e887380df.png">

# Chromeのアプリを起動する

表示させたアプリにクリックイベントを設定し、アプリを起動できるようにします。

アプリを起動するには```launchApp``` メソッドを使用し、
引数には```getAll```で取得した```app```の```id```を指定します。

```js
chrome.management.launchApp(app.id);
```

```launchApp```は今開いているNew Tab Pageでアプリが起動するのではなく、
新しいTabを開いてアプリを起動します。
アプリが起動するとNew Tab Pageは不要なので、
閉じる処理を追加してあげると良いでしょう。

```js
chrome.management.launchApp(app.id);
if (app.launchType === "OPEN_AS_REGULAR_TAB") window.close();
```

Chromaのように新しいWindowを開いて起動するアプリの場合は
New Tab Pageを閉じる必要はないので、
```app.launchType``` で起動方法をチェックして、```OPEN_AS_REGULAR_TAB```の場合のみ
New Tab Pageを閉じてあげます。


Chromeのアプリを取得して、クリックイベントを設定して表示するサンプルです。
ご参考までに。

```js
function getApps() {
  chrome.management.getAll(apps => {
    apps.forEach(app => {
      if (app.enabled && app.isApp) {
        setApp(app);
      }
    });
  });
}

function setApp(app) {
  const li = document.createElement("li");
  li.className = "apps-list-app";
  li.innerHTML = `
    <img class="apps-image" src="${app.icons[0].url}"/>
    <span class="appId-${app.id} apps-name">${app.shortName}</span>
  `;
  document.querySelector(".apps-list").appendChild(li);

  li.addEventListener("click", () => {
    chrome.management.launchApp(app.id);
    if (app.launchType === "OPEN_AS_REGULAR_TAB") window.close();
  });
}
```

# 最後に

![a.mov.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/207520/16b328ff-aaf2-2833-0b5b-a789b77f5dc6.gif)

私のNew Tab Page はこんな感じで
メモ欄を他の端末と共有できるようにしています。

TwitterのTLやQiitaの記事一覧などを表示させてみるのも面白いかもしれません。

自分の好きなNew Tab Pageを作ってみてはいかがでしょうか！

# 参考
- https://developer.chrome.com/extensions/override
- https://qiita.com/sqrtxx/items/19fd2114430e9e1fb57f