概要
ブックマークレットはブックマーク一覧からユーザが「開く」ことでスクリプトを実行する一方、ユーザスクリプトはあるWebページのロード時に自動でスクリプトが実行されるように(URLフィルタなどで)設定することができる。
ユーザスクリプトの作成にあたって、バージョン情報やURLフィルタを埋め込むヘッダ(メタデータ)を付ける必要があるものの、それ以外では特別な記法などは特に要求されず、通常の(Webページ上で動作する)JavaScriptと同じように記述すればいいらしい。
さて、ユーザスクリプトの実行にはこれを実現するための拡張機能の導入が必要な場合がある。Chromeでは標準機能に含まれており、chrome://extensions
にローカルのjsファイルをD&Dすることで通常の拡張機能と並べてユーザスクリプトを扱える。一方、Firefoxでは(今のところ)別途拡張機能の導入が必要らしい。
(2021/03/19 追記)Google Chromeでローカルのjsファイルをインストールする際、拡張子を.user.js
にする必要があるみたい。.js
だとブラウザのタブで開いてしまう(Linux版 Google Chrome 89)。
代表例っぽいものを例示する。むかし同様のコンセプトのScriptAutoRunner(GitHub)というのを見かけたが、(これは更新されていないし)ちまたでは*monkeyというものが使われているらしい。
- Firefox
- Chrome
- Greasemonkey(標準機能として統合)
- Tampermonkey - Chrome ウェブストア
拡張機能のGreasemonkey、TampermonkeyにはどちらもGUIが存在し、GUI上でユーザスクリプトの追加、URLフィルタの設定(スクリプト外で別途指定する場合)、有効・無効化を行う。Greasemonkeyは管理はpopup上のみでエディタ用のpageがあり、Tampermonkeyはpopupもpageも管理に使えて、こちらもエディタ用のpageありっぽい。
これらは特殊API(@grant
)以外の点では互換性がありそう。
環境
- Google Chrome 80
- Firefox 74
- Greasemonkey 4.9
- Tampermonkey 4.10
Greasemonkey(Firefox拡張機能)
新規作成時テンプレート
// ==UserScript==
// @name Unnamed Script 000000
// @version 1
// @grant none
// ==/UserScript==
すべてのWebページ(http, https)
// ==UserScript==
// @name Unnamed Script
// @include http*
// @version 1
// @grant none
// ==/UserScript==
console.log("Hello!");
すべてのページ
// ==UserScript==
// @name Unnamed Script
// @include *
// @version 1
// @grant none
// ==/UserScript==
console.log("Hello!");
example.com
// ==UserScript==
// @name Unnamed Script
// @match http://example.com/*
// @version 1
// @grant none
// ==/UserScript==
console.log("Hello example.com!");
Tampermonkey(Firefox拡張機能)
新規作成時テンプレート
※ @match
には作成時に開いていたページのURLが自動入力される
// ==UserScript==
// @name New Userscript
// @namespace http://tampermonkey.net/
// @version 0.1
// @description try to take over the world!
// @author You
// @match http://example.com/
// @grant none
// ==/UserScript==
(function() {
'use strict';
// Your code here...
})();
example.com
// ==UserScript==
// @name New Userscript
// @namespace http://example.com
// @version 0.1
// @description try to take over the world!
// @author You
// @match http://example.com/*
// @grant none
// ==/UserScript==
(function() {
'use strict';
console.log("Hello example.com!");
})();
メタデータの指定
キー | 値 |
---|---|
name | スクリプト名 |
namespace | 名前空間。作成者のWebページ等を指定し、ユーザスクリプトリポジトリが同名のユーザスクリプトを区別できるようにする |
version | バージョン |
description | 説明文 |
author | 作成者 |
match | URLフィルタ(推奨)。厳格なルールに基づいてパターンマッチングする(実行範囲の面でより安全)。複数指定可(仕様) |
include | URLフィルタ。マッチするURLを含める。複数指定可(仕様) |
exclude | URLフィルタ。マッチするURLを除外する。複数指定可(仕様) |
grant | ユーザスクリプト用の特殊APIへのアクセス設定。複数指定可 |
require | URLから外部js(ライブラリ)を呼び出し。複数指定可 |
必要なものを指定する。
- Metadata Block - GreaseSpot Wiki
- metadata - What is the Greasemonkey namespace needed for? - Stack Overflow
特殊API(grant)
Greasemonkeyの場合、grantを省略するとnone
扱い。Tampermonkeyの場合、省略するとスクリプト中で使用されているAPIが自動で設定される(らしい)。
Greasemonkey:GM.setValue
、GM.getValue
// @grant GM.setValue
// @grant GM.getValue
Tampermonkey:GM_setValue
/GMApi.GM_setValue
、GM_getValue
/GMApi.GM_getValue
// @grant GM_setValue
// @grant GM_getValue
これらは*monkeyで実行されるスクリプト間で共通のストレージの値を読み書きするらしい(GM.setValue - GreaseSpot Wiki)。
ライブラリ・外部js呼び出し(require)
// @require /js/example.js
// @require ../js/example.js
// @require https://cdnjs.cloudflare.com/ajax/libs/jquery/3.4.1/jquery.min.js
CORS(Same-origin policy)
ブックマークレットのオリジンは表示中のWebページになる。ユーザスクリプトのオリジンはどうか。
// 比較用ブックマークレット
javascript:console.log(location.origin);
// ==UserScript==
// @name Check origin
// @namespace http://example.com
// @version 0.1
// @description try to take over the world!
// @author You
// @match http://example.com/*
// @grant none
// ==/UserScript==
(function() {
'use strict';
console.log(location.origin);
})();
Chrome標準機能、Firefox Greasemonkey、Firefox Tampermonkeyでhttp://example.com
。
セキュリティ
セッションID(クッキー)でもフォームに入力されたパスワードでもなんでも読み出し/書き換え/送受信可能なので、任意ユーザの作ったスクリプトを使用する際は(他のプログラム同様)セキュリティに気をつけましょう..。