Greasemonkeyによるアプリケーション開発

第2回 Greasemonkeyでカレンダアプリを作ってみる:まずはシンプルに。

この記事を読むのに必要な時間:およそ 10.5 分

見栄えを調整する

第2の不満は

「ページの一番上に表示されてしまい,スクロールすると見えなくなってしまう・見栄えがよくない。」

でした。これはCSSを設定することで解決できます。GreasemonkeyではCSSを追加設定するためのGM_addStyle関数が用意されていますので,これを利用することにします。

図7のユーザスクリプトのmakeCalendarTable関数の処理に,タグ要素にid属性やclass属性の値を設定する処理を追加して,CSSを設定しやすいようにします。そして,GM_addStyle関数でCSSを設定します。その結果が図8のユーザスクリプトです。

図8 CSSを使ってカレンダの見栄えを向上させたユーザスクリプト(ユーザスクリプトはこちら

// ==UserScript==
// @name         mini_calendar3
// @namespace    http://gomaxfire.dnsdojo.com/
// @description  the 3rd mini calendar
// @include      *
// ==/UserScript==

//  図5のユーティリティ関数群をここで定義するが省略

function makeCalendarTable(){
  // 関数内で共通に利用する変数を定義 -(1)	 
  var CSS_PREFIX = "_gcal_";
  var DAYS = "Sunday Monday Tuesday Wednesday Thursday Friday Saturday".split(" ");
  var TODAY = new Date();
  var TODAY_DATE = TODAY.getDate();
  var TODAY_MONTH = TODAY.getMonth();
  
  var table = $table({id:css("")}); 
  setMonthHeader();
  setDayHeader();
  setDates();
  setStyle();
  return table;
  
  /**
   *  表示中のページ内のCSSで使われているクラス名との衝突をさけるため,
   *  適当にプレフィックスをつけることにする。そのための補助関数。 -(1)
   */
  function css(name){
    return CSS_PREFIX + name;
  }

  function setMonthHeader(){
    var d = new Date();
    var year = d.getFullYear();
    var month = d.getMonth() + 1;

    // -(1)
    $add(table, 
         $add($tr({className:css("header")}),  
              $add($th({className:css("header"), colSpan:7}), year + "/" + month))); 
  }
  
  function setDayHeader(){
    var tr = $tr({className:css("dayNames")});
    // 曜日名を示す配列は日にちを示すtd要素のclass名にも
    // 流用するために外側で定義した -(1)
    DAYS.forEach(function(day){
        $add(tr, 
             $add($th({className:[css(day),css("dayName")].join(" ")}), 
                  day.substring(0,1)));
      });
    $add(table, tr);
  }
  
  function setDates(){
    var d = new Date();
    var nextMonth = d.getMonth() < 11 ? d.getMonth() + 1 : 0;
    d.setDate(1);
    d.setDate(-d.getDay() + 1);
    
    var finish = false;
    for(;;){
      var tr = $tr();
      for(var i=0;i<7;i++){
        var td = $add($td(), d.getDate());
        setClassName(td, d);  // 日にちによって見栄えを変える -(1)
        $add(tr, td);
        d.setDate(d.getDate() + 1);
        if(d.getMonth() == nextMonth) finish = true;
      }
      $add(table, tr);
      if(finish)break;
    }

    /**
     * 日にち表現用td要素を,その日にちによって見栄えが変わるよう
     * class属性を設定する -(1)
     */
    function setClassName(td, d){
      var buffer = [];
      if(d.getMonth() == TODAY_MONTH){
        buffer.push(css("onDate"));
        buffer.push(css(DAYS[d.getDay()]));
        if(d.getDate() == TODAY_DATE){
          buffer.push(css("today"));
        }
      } else {
        buffer.push(css("outDate"));
      }
      td.className = buffer.join(" ");
    }
  }

  /**
   * GM_addStyle関数を使ってCSSを設定する -(2)
   */
  function setStyle(){
    var style =
      <><![CDATA[
                 #_gpanel{
                   margin:0px;
                   padding:0px;
                   position:fixed;
                   top:0;
                   left:0;
                   z-index:999999;
                   width:10px;
                   background:transparent;
                   border-collapse: separate;
                 }
   // 長いので中略
                 #_gcal_ td._gcal_today {
                   color : gold;
                   font-weight : bold;
                   border-top : 1px solid white;
                   border-left : 1px solid white;
                   border-bottom : 1px solid #666666;
                   border-right : 1px solid #666666;
                   background-color:#FFFFEE;
                 }
                 ]]></>;
    GM_addStyle(style);
  }
}

// CSSで左上隅に配置するようにしたので,bodyの末尾要素に追加してもよい。
// そのためコーディング量が少なくてすむinsertBeforeではなくappendChildにした。
document.body.appendChild($add($div({id:"_gpanel"}), makeCalendarTable()));

基本的な処理方法は図7と変わっていません。変更点は大きく見ると2点で,⁠1)CSS用にid属性とclass属性を各要素に追加する処理を加えたことと,⁠2)GM_addStyle関数を使ってCSSを設定するsetStyle関数を追加したこと,です。

図8内に(1)⁠2)の変更点に関わる箇所についてコメントでも示しておきました。⁠2)のsetStyle関数ではE4Xで<></>の子要素としてCDATAセクションを使うことでヒアドキュメントライクにCSSを記述しています。また,そこで定義しているCSSでスクロールしても常に画面の左上隅に表示されるようにプロパティを設定しています。

以上で第2の不満も解消できました。

著者プロフィール

gotin(ゴチン:GOrdon TImothy Nathanson)

会社員です。肩書きは特にありません。Greasemonkeyは会社の後輩が使っていてそれ面白いじゃんって思って使い始めました。自宅サーバで作ったRuby on Railsな自作ブログツールで作った自作ブログにGreasemonkeyのユーザスクリプトを載せたりもしていたんですが,誰にも読んでもらえなくて寂しかったのです。で,作ったままほったらかしにしていたはてなダイアリーに載せたら自作ブログよりかはありがたいことに多少読んでもらえるようになり,その後いろいろあって,そして今ここにいます。

URLhttp://d.hatena.ne.jp/gotin/