閑古鳥

オールドプログラマの日記。プログラミングとか病気(透析)の話とか。

// Copyright (C) 2005, d:id:wata_d.
//
// ==UserScript==
// @name          Hatena Diary DateEdit
// @namespace     http://d.hatena.ne.jp/wata_d
// @include       http://d.hatena.ne.jp/*/edit*
// ==/UserScript==

(function()
{
    var httpReq = null;
    
    function getTagValue(input, attr)
    {
        for(var i = 0; i < input.length; ++i)
        {
            if(input[i].name == attr) { return input[i].value; }
        }
    }

    //! html から textarea要素の中身を取り出す
    // ここの処理は割といい加減なので、もう少しスマートな形に書き換える
    function getTextareaValue(text)
    {
        // textの中身は html の 1 ページ
        // XML ではないので文字列処理をして抜き出さなければならない...
        var startIdx = text.indexOf("<textarea");
        var endIdx = text.indexOf("</textarea>");

        var ret = text.substring(startIdx, endIdx);
        // この段階で ret の中に textarea の開始タグがあるので取り除く
        endIdx = ret.indexOf(">") + 1;
        ret = ret.substring(endIdx, ret.length);

	// < > & " が実体参照になっているので展開する
	ret = ret.replace(/&lt;/g, "<");
	ret = ret.replace(/&gt;/g, ">");
	ret = ret.replace(/&quot;/g, "\"");
	ret = ret.replace(/&amp;/g, "&");

        return ret;
    }

    //! year年month月day日の記事を読み込む
    function doLoadDiary(year, month, day)
    {
        var idx = location.href.lastIndexOf("?");
        if(idx == -1) { idx = location.href.length; }

        idx -= 4; // 「edit」を消すため(泥縄)
        // http://.../user/edit?date=yyyymmdd を取得する
        var uri = "edit?date=" + year + month + day;
        uri = encodeURIComponent(uri);
        // uri のページからその日の記事を引っ張ってくる
        httpReq = new XMLHttpRequest();
        httpReq.open("GET", uri, true);
        httpReq.send("");
        httpReq.onreadystatechange = loadedDiary;
    }
    //! 過去日記の読み込みを完了したらこのイベントが呼ばれる
    function loadedDiary()
    {
        if(!httpReq) { return; }
        
        if(httpReq.readyState == 4)
        {
            var targetDayEntry = getTextareaValue(httpReq.responseText);
            // textareaに拾ってきた記事を挿入する
            var textarea = document.getElementById("textarea-edit");
            if(textarea)
            {
                textarea.value = targetDayEntry;
            }
        }
    }
    
    //! ボタンを作って返す
    function createButton()
    {
        var input = document.createElement("input");
        input.type = "button";
        input.value = "\u65E5\u4ED8\u5909\u66F4"; // 日付変更
        input.onclick = dateSetting;
        input.className = "field";
        return input;
    }
    //! 「日付変更」ボタン押下時のイベント
    function dateSetting()
    {
        // 年月日取得
        var input_tags = document.getElementsByTagName("input");
        var year = getTagValue(input_tags, "year");
        var month = getTagValue(input_tags, "month");
        var day = getTagValue(input_tags, "day");

        doLoadDiary(year, month, day);
    }

    //! メイン処理(ここが一番最初に呼ばれる)
    window.addEventListener("load",
        function(e)
        {
            // 今現在, 日付を設定する input 要素は h3 要素の子になっており,
            // また h3 要素はひとつしか存在していない
            var h3 = document.getElementsByTagName("h3");
            if(h3 && h3.length)
            {
		var success = false;
		var heading = h3[0];
		// 子に input 要素がある時のみ有効(プレビュー時にボタンが出てしまうのを防ぐため)
		for(var i = 0; i < heading.childNodes.length; ++i)
		{
		    if(heading.childNodes[i].nodeName == "INPUT")
		    {
			success = true; break;
		    }
		}

		if(success)
		{
		    heading.appendChild(createButton());
		}
            }
        }
    , false);
}
)();