Chromeの拡張機能を作ってみた 〜Markdown形式のリンクを作成する拡張機能〜
勉強メモ程度に書きました
ソースはこちら
構成
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
参考にした記事
めちゃ分かりやすかったですありがとうございました。
いざ実装
こんな形式でコピーしてクリップボードに記録してくれるやつを作る。
[表示名](https://hoogehoge.com "title")
manifestの作成
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の読み込みを行う。
<!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
console.log("Hello Extension!");
Chromeでの動作確認をする
- chrome://extensions にアクセス
- 「パッケージ化されていない拡張機能を読みこむ」をクリック
- 拡張機能のフォルダを選択(ZIPになっている必要はありません)
- 問題なければ拡張機能の一つとして追加されます。問題があればエラー内容が出るので、修正すること。(出るとするとmanifestの文法エラー)
- 右上に作成した拡張機能が追加されているはずなのでクリック
- HTMLが表示されればOK。更にポップアップ表示された部分を右クリック、検証。
ポップアップで表示された部分は処理的には別ページなので、表示されているページを検証してもコンソールには何もでない。 - 開発者ツールが別ウィンドウで表示されるはずなので、そこのコンソールに出力されていることを確認して微笑む。
やっとちゃんと実装
ページタイトルとURLを取得して、Markdownに整形したものをconsoleに出力する処理を実装してみる。
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に以下を追記
"permissions":["clipboardRead","tabs"]
これでTAB関連のAPIと、クリップボードへのアクセスが可能になります。
そしてmain.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とか調整して完成です!
ソースはこちら
追記 今わかっているバグ
- 複数ウィンドウを開いていると、親ウィンドウ(?)で開いているタブしか対象にされない