Markdown形式のリンクを作成するChrome拡張機能を作ってみた（メモ）

# Chromeの拡張機能を作ってみた　〜Markdown形式のリンクを作成する拡張機能〜

勉強メモ程度に書きました
ソースは[こちら](https://github.com/spadeloves/markdown_link_maker "spadeloves/markdown_link_maker: Chrome extension to make markdown link text")

## 構成
Chromeの拡張機能はHTML、CSS、JavaScriptで出来ている。
こいつらと、Manifest fileをひとまとめにして、zip圧縮することでストアに公開することが出来る。また、chrome://extensions/ にドラッグドロップすると、インストールできる。

オプションのページや、ボタンなどの見た目の部分はHTMLとCSSで、処理はJSで実装する。
拡張機能内では、chrome.APIと呼ばれるAPIを使うことが出来る。
https://developer.chrome.com/extensions/api_index
具体的に何が出来るかは以下
https://developer.chrome.com/extensions/samples
サンプルソースもあるよ

## Manifest file
JSON形式で書く拡張機能の情報を記したファイルです。

具体的には拡張機能の名前、説明、使用するスクリプトのパス、APIのパーミッションなどを書く。
公式ドキュメント - https://developer.chrome.com/extensions/manifest

## 参考にした記事
* [Chrome拡張の開発方法まとめ　その1：概念編](https://qiita.com/edit-mode/items/26d7a22233ecdf48fed8 "Chrome拡張の開発方法まとめ　その1：概念編")
* [マニフェストファイルの書き方](https://qiita.com/mdstoy/items/9866544e37987337dc79 "マニフェストファイルの書き方")

めちゃ分かりやすかったですありがとうございました。

# いざ実装

こんな形式でコピーしてクリップボードに記録してくれるやつを作る。

```md
[表示名](https://hoogehoge.com "title")
```

### manifestの作成
manifest.jsonを見よう見まねで作成

manifest.json

```manifest.json
{
	"manifest_version": 2,
	"name": "Markdown Link Maker",
	"version": "1.0",
	
	"description": "Copy text the Link text written in Markdown",
	"icons": {
		"48": "icon/icon48.png"
	},
	"browser_action": {
		"default_icon": {
			"48": "icon/icon48.png"
		},
		"default_title": "Make Markdown Link",
		"default_popup": "popup.html"
	}
}
```

browser_actionとは、Chromeの右上に表示される拡張機能のアイコンをクリックした際に、行われるアクションのことです。この記述だと、クリックした際にpopup.htmlがポップアップ表示される事になります。

#### manifestの注意点
* jsonで次の項目がないのにカンマを付けないこと
* default_localeは_localesフォルダが存在しない場合は記述しちゃだめ

### popup.htmlを書く
テキトーに書いた。
とにかくクリックされたときに表示する内容と、処理を実行するJSの読み込み、CSSの読み込みを行う。

```html
<!DOCTYPE html>
<html lang="en">
<head>
	<meta charset="UTF-8">
	<title>Document</title>
	<link rel="stylesheet" href="icon.css">
	<link rel="stylesheet" href="style.css">
	<script src="js/jquery-3.2.1.min.js"></script>
</head>
<body>
	<div style="width: 200px;">
		<p style="margin: 0 auto; display: block;text-align: center;">
			Markdown Link Copied!
		</p>
	</div>
</body>
	<script src="js/main.js" type="text/javascript"></script>
</html>
```

#### 注意点
* 特に無い！！！！本当にただHTMLを書くだけでよい
* さっきも言ったけどGUIの記述と、CSS，JSの読み込みだけ（今回はボタンとかもないのでメッセージのみ）

### main.js　の前にHello worldをやっとく
動作確認も込めて、Hello Worldをやってみる
とりあえずmain.jsを雑に作成

main.js

```main.js
console.log("Hello Extension!");
```

#### Chromeでの動作確認をする
1. chrome://extensions にアクセス
2. 「パッケージ化されていない拡張機能を読みこむ」をクリック
3. 拡張機能のフォルダを選択（ZIPになっている必要はありません）
4. 問題なければ拡張機能の一つとして追加されます。問題があればエラー内容が出るので、修正すること。（出るとするとmanifestの文法エラー）
5. 右上に作成した拡張機能が追加されているはずなのでクリック
6. HTMLが表示されればOK。更にポップアップ表示された部分を右クリック、検証。
ポップアップで表示された部分は処理的には別ページなので、表示されているページを検証してもコンソールには何もでない。
7. 開発者ツールが別ウィンドウで表示されるはずなので、そこのコンソールに出力されていることを確認して微笑む。

### やっとちゃんと実装
ページタイトルとURLを取得して、Markdownに整形したものをconsoleに出力する処理を実装してみる。


```js
var url = $(location).attr('search');
var title = $("title").text();

console.log("["+ title + "](" + url + '"' + title + '")');
```

結果　```[Document]("Document")``` ( ﾟдﾟ)

main.jsはあくまでもpopup.htmlの上で動いているので、locationで取れるのはpopup.htmlの情報だけなのです。
表示しているページの情報（DOM要素）へアクセスするには、実施のページ上でJSを動かす必要があります。

・・・が！今回はChromeAPIをつかってサクッと実装します。

manifestに以下を追記

```js
"permissions":["clipboardRead","tabs"]
```

これでTAB関連のAPIと、クリップボードへのアクセスが可能になります。
そしてmain.jsに以下のように記述

```js
//main 
chrome.tabs.query({active:true}, function(tab) {
	chrome.tabs.sendMessage(tab[0].id, {text:''}, function(response) {
		url = tab[0].url;
		title = tab[0].title;
	result = "["+ title + "](" + url + ' "' + title + '")';
	execCopy(result);
	});
});

//copy to clipbored
function execCopy(string){
	var temp = document.createElement('div');
	temp.appendChild(document.createElement('pre')).textContent = string;
	var s = temp.style;
	s.position = 'fixed';
	s.left = '-100%';
	document.body.appendChild(temp);
	document.getSelection().selectAllChildren(temp);
	var result = document.execCommand('copy');
	document.body.removeChild(temp);
	return result;
}
```
*chrome.tabs.sendMessage* でタブにリクエストを送信し、タブの情報を受け取っています。
あとは中身を整形して、markdownの形でクリップボードに貼っつけるだけ。

HTMLとか調整して完成です！
ソースは[こちら](https://github.com/spadeloves/markdown_link_maker "spadeloves/markdown_link_maker: Chrome extension to make markdown link text")

# 追記 今わかっているバグ

- [ ] 複数ウィンドウを開いていると、親ウィンドウ（？）で開いているタブしか対象にされない