2016-06-05 ,

Google Calendarで過ぎた日の色を変える

カレンダーの過ぎた日に斜線を引くのが好きな私としては、過ぎた日が一目で分かるようにして欲しいのです。

例えば次のようなユーザースクリプトを作ってGreasemonkeyなりTampermonkey使えば出来るわけですが、まぁ、やりたいことの些細さに比べて面倒ですね。

(追記2018-11-14: デザインが変わって動かなくなっていたので Google Calendarで過ぎた日の色を変える(2018) を書きました)

(function(){
    var PAST_COLOR = "#e0e0e0";
    var PAST_BORDER_LEFT = "1px solid #d0d0d0";
    var TODAY_COLOR = "#ffa";

    var timer = null;
    function schedule(){
        if(timer){
            clearTimeout(timer);
        }
        timer = setTimeout(update, 100);
    }

    function update(){
        if(document.getElementsByClassName("st-bg-today").length === 0){
            return;
        }

        var bgs = Array.prototype.slice.call(document.getElementsByClassName("st-bg"));
        bgs.find(function(e,i,a){
            if(e.className.match("st-bg-today")){
                e.style.backgroundColor = TODAY_COLOR;
                return true;
            }
            else {
                //e.className += " st-bg-past";
                e.style.backgroundColor = PAST_COLOR;
                e.style.borderLeft = PAST_BORDER_LEFT;
                return false;
            }
        });
        var dtitles = Array.prototype.slice.call(document.getElementsByClassName("st-dtitle"));
        dtitles.find(function(e,i,a){
            if(e.className.match("st-dtitle-today")){
                e.style.backgroundColor = TODAY_COLOR;
                return true;
            }
            else {
                //e.className += " st-dtitle-past";
                e.style.backgroundColor = PAST_COLOR;
                e.style.borderLeft = PAST_BORDER_LEFT;
                return false;
            }
        });
    }

    var observer = new MutationObserver(schedule);
    observer.observe(document.body, {childList:true, subtree:true});

    update();
})();

月表示や4週間表示の時、各日付の枠(td)には st-bg というクラスが付いています。 今日の日付をグレーにするためか、 st-bg-today というクラスも用意されていて、 今日の日付の枠は st-bg st-bg-today というクラスが付きます。

なので、クラスst-bgが付いている要素をgetElementsByClassNameで列挙して、 先頭からst-bg-todayが付いている要素に到達するまで背景色を変えることにしました。

今日の日付(st-bg-today)がカレンダー内にない場合もあります。 本来なら、過去のカレンダーか未来のカレンダーかを判別して、 全部色を変えるか全く色を変えないか判断しなければなりません。 面倒なので、st-bg-todayが無ければ何もしないようにしました。

日付の数字部分(td.st-dtitle)の背景には不透明な白が指定されています。 そのままだとせっかく背景の色を変えても数字部分だけ白くなってしまいます。 transparentを指定したら良いのかと思ったのですが、 カレンダーの1行がわずかに次の行と重なっているため、 数字部分の上の方が前の行の背景色になってしまいます。 div.month-rowのheightが4行の時は26%、5行の時は21%となっていて、 これを25%や20%にするとぴったり収まります。 なぜ1%余計に大きくしているのでしょうか。 無理矢理1%小さくする方法も考えたのですが、 Googleは今日の日付の色を変えるために.st-bg-todayと.st-dtitle-todayの両方の backgroundを指定していますので、それにならって.st-dtitleの色も.st-bg と同様に変更することで解決しました。

最初はst-bg-pastとst-dtitle-pastというクラスを付加するようにしたのですが、 別途Stylish等でユーザースタイルを指定するのが面倒だったので 直接ユーザースクリプトで色を変えるようにしてしまいました。

MutationObserverのコールバック頻度はどのように決まっているのでしょうか。 今ひとつ分からなかったので、タイマーを併用して最後の更新から100ms後に 色替えを実行することにしました。

Googleのプロダクトはかゆいところに全く手が届かないのが困りものですよね。 あまり細かいカスタマイズが必要ならGoogle Calendar APIを使用して 自分でカレンダーを作るなり、他の既成のカレンダーを探すなりした方が良いかも しれません。

FullCalendar - JavaScript Event Calendar (jQuery plugin)

Pingback / Trackback