前回はGreasemonkeyの基本的な使い方について解説しました。今回からは本題の通りGreasemonkeyによるアプリケーション開発の話を進めていきたいと思います。
どのページを開いていても,ちらっとカレンダを見ることができたら便利ですよね?(「ちょっと首傾けるだけで本物の紙のカレンダを見ることができてすでに便利だ,これ以上カレンダなんていらないよ」という方,今すぐそのカレンダもしくはあたなの席を移すか,そのカレンダを捨てさってください)(←これは冗談ですよ。念のため) 少なくとも私は便利に思いました。そこでページ内にカレンダを表示する機能をGreasemonkeyによるアプリケーションとして実現することとします。具体的には図1のようなカレンダをページ内に表示できるようにします。
カレンダを命令一発で表示できるとよいのですが,そんな魔法はありません(魔法のようなカレンダライブラリは世の中にすでにあると思いますが,ここではそのようなライブラリに頼るのはやめます)。少なくとも私は知りません。javascriptに標準で用意されているDateオブジェクトとDOM操作を駆使して作成することにします。
まずはカレンダを表現するHTMLをそのままページに挿入してみる
まずは単純にその月のカレンダを表示することから取りかかります。HTMLのTABLE(とTR,TH,TD)タグを利用してカレンダを表示することとします。できあがりのHTMLは図2のようになることを想定しています。
図2 2007年8月のカレンダを表すHTML
<table>
<tr>
<th colspan="7">2007/8</td>
</tr>
<tr>
<th>S</th><th>M</th><th>T</th><th>W</th><th>T</th><th>F</th><th>S</th>
</tr>
<tr>
<td>29</td><td>30</td><td>31</td><td>1</td><td>2</td><td>3</td><td>4</td>
</tr>
<tr>
<td>5</td><td>6</td><td>7</td><td>8</td><td>9</td><td>10</td><td>11</td>
</tr>
<tr>
<td>12</td><td>13</td><td>14</td><td>15</td><td>16</td><td>17</td><td>18</td>
</tr>
<tr>
<td>19</td><td>20</td><td>21</td><td>22</td><td>23</td><td>24</td><td>25</td>
</tr>
<tr>
<td>26</td><td>27</td><td>28</td><td>29</td><td>30</td><td>31</td><td>1</td>
</tr>
</table>
この形式のHTMLを実行時点の月に合わせて作成すればよいわけですが,まずは試しに固定的に2007年8月の月間カレンダを表すHTMLを用意して,それをページ内に出力するユーザスクリプトを作成してみます。
今回最初のユーザスクリプトは図3です。
図3 2007年8月のカレンダをページ上に表示するユーザスクリプト(ユーザスクリプトはこちら)
// ==UserScript==
// @name mini_calendar1
// @namespace http://gomaxfire.dnsdojo.com/
// @description the 1st mini calendar
// @include *
// ==/UserScript==
var table = // (1)
<table border="1">
<tr>
<th colspan="7">2007/8</td>
</tr>
<tr>
<th>S</th><th>M</th><th>T</th><th>W</th><th>T</th><th>F</th><th>S</th>
</tr>
<tr>
<td>29</td><td>30</td><td>31</td><td>1</td><td>2</td><td>3</td><td>4</td>
</tr>
<tr>
<td>5</td><td>6</td><td>7</td><td>8</td><td>9</td><td>10</td><td>11</td>
</tr>
<tr>
<td>12</td><td>13</td><td>14</td><td>15</td><td>16</td><td>17</td><td>18</td>
</tr>
<tr>
<td>19</td><td>20</td><td>21</td><td>22</td><td>23</td><td>24</td><td>25</td>
</tr>
<tr>
<td>26</td><td>27</td><td>28</td><td>29</td><td>30</td><td>31</td><td>1</td>
</tr>
</table>;
var div = document.createElement("div"); // (2)
div.innerHTML = table.toSource(); // (3)
document.body.insertBefore(div, document.body.firstChild); // (4)
(1)でカレンダを表すHTMLをE4Xを使って変数tableにセットしています。E4XはECMAScriptにXMLを表現する文法とセマンティクスを追加する拡張仕様です。仕様について詳しくはECMAのページに載っているドキュメントに示されていますが,ここではXMLをインラインで記述することでxml型の値を表すことができ,xml型の値はtoSource関数を呼び出すことでそのxmlの文字列表現を取得することができる,ということだけ分かればこのユーザスクリプトの処理は理解できると思います。
(2)でdiv要素を作成し,(3)でその内側のhtmlを(1)で作成したカレンダを示すhtmlに設定しています。最後に(4)でページのbody要素の先頭に作成したdiv要素を追加しています。
このユーザスクリプトを実行すると,図4のように質素なカレンダが表示されます。
最初の単純なユーザスクリプトとしてはできは上々だと思いますが,まだまだもの足りません。以下のような不満があると思います。
- (1) 常に2007年8月に固定のカレンダである。実行時の月のカレンダにしたい。
- (2) ページの一番上に表示されてしまい,スクロールすると見えなくなってしまう・見栄えがよくない。
- (3) 常にカレンダが表示されているのは邪魔である。必要なときだけ表示するようにしたい。
上から順に不満を解決していきたいと思います。

