TiddlyWiki 切り替え可能なカレンダー・改

以前、カレンダーを作成した。
TiddlyWiki (切り替え可能なカレンダー) - じゅんじゅんのきまぐれ
これが、IEでしか動かなかったのと、警告の出る理由が分かったので、修正。
Firefox対応のみですけど。




ちなみに、警告の出る理由は、多分ですが、
「onClickで動作するMacroは、falseを返さないと警告を出す」
ようです。なるほど。


修正は、五点

  • onClick動作の関数のreturnをfalseに。
  • FireFoxでは、innerTextでなくtextContent
  • FireFoxでは、Arrayのlengthは、入ってる数(IEだと、コンストラクタの確保数だった)
  • 親の取得は、IE:parentElement / Firefox:parentNode
  • Date の getYear() が、IE:年数(2009とか) / Firefox:1900年基準の年数(109とか)

年数の修正は、もっと上手い方法がある気がするけど、考えるのが面倒だったので、
1000より小さい値なら、1900を足す、としたので、このマクロでは、1000年より前は出せませんね。


以下がソースとなりまする。

//{{{
config.macros.viewCalendar = {
	handler: function(place,macroName,params) {
		// read parameters
		var targetDate = this.getTargetDate(params[0], true);
		var special = params[1] ? params[1] : "";
		var journalFormat = params[2] ? params[2] : "DD MMM YYYY";
		var displayFormat = params[3] ? params[3] : "DD";
		var todayColor = params[4] ? params[4] : "#CCFFFF";
		var diffeMon = params[6] ? params[6] : "#CCCCCC";
		var satColor = params[7] ? params[7] : "#CCCCFF";
		var sunColor = params[8] ? params[8] : "#FFCCFF";
		var speColor = params[5] ? params[5] : sunColor;
		var startDay = params[9] ? Number(params[9]) : 0;
		var headerStr = params[10] ? params[10] : "SunMonTueWedThuFriSat";
		var headerAlign = params[11] ? params[11] : "center";
		var bodyAlign = params[12] ? params[12] : "right";
		var paraLen = params.length;
		var weekNum = 7;

		// init
		var startDate = new Date();
		startDate.setHours(0);
		startDate.setMinutes(0);
		startDate.setSeconds(0);
		startDate.setMilliseconds(0);
		var nToday = startDate.getTime();
		nTime = targetDate.getTime();
		var nTargetDay = targetDate.getDay();
		if(nTargetDay < startDay) nTargetDay += weekNum;
		startDate.setTime(nTime - (nTargetDay - startDay) * 24 * 3600000);
		var nTargetYear = targetDate.getYear();
		var nTargetMonth = targetDate.getMonth();

		// make header
		var theTable = createTiddlyElement(place, "table");
		theTable.setAttribute("paraLen", paraLen);
		for(i=0; i < paraLen; i++) {
			theTable.setAttribute("para"+i, params[i]);
		}
		var theTableHead = createTiddlyElement(theTable, "thead");
		theTableHead = createTiddlyElement(theTableHead, "tr");
		var headerLen = headerStr.length / weekNum;
		for(i=startDay; i < startDay + weekNum; i++) {
			var e = createTiddlyElement(theTableHead, "th", null, null, headerStr.substr(headerLen*(i%weekNum),headerLen));
			e.align = headerAlign;
		}

		// make body
		var reSla = new RegExp("/","g");
		var theTableBody = createTiddlyElement(theTable, "tbody");
		while((startDate.getYear() == nTargetYear && startDate.getMonth() <= nTargetMonth) || startDate.getYear() < nTargetYear) {
			var theTableRecord = createTiddlyElement(theTableBody,"tr");
			for(i=0; i < weekNum; i++) {
				var theElement = createTiddlyElement(theTableRecord,"td");
				theElement.align = bodyAlign;
				var e = createTiddlyLink(theElement, startDate.formatString(journalFormat), false);
				createTiddlyText(e, startDate.formatString(displayFormat));
				// paint backgroundColor
				var re = new RegExp(startDate.formatString(journalFormat).replace(reSla,"\\/"));
				if(startDate.getMonth() != nTargetMonth) theElement.style.backgroundColor = diffeMon;
				else if(startDate.getTime() == nToday) theElement.style.backgroundColor = todayColor;
				else if(special.match(re)) theElement.style.backgroundColor = speColor;
				else if(startDate.getDay() == 6) theElement.style.backgroundColor = satColor;
				else if(startDate.getDay() == 0) theElement.style.backgroundColor = sunColor;
				startDate.setTime(startDate.getTime() + 24 * 3600000);
			}
		}
	},

	getTargetDate: function(param, first) {
		// read parameters
		var targetDate = new Date();
		targetDate.setHours(0);
		targetDate.setMinutes(0);
		targetDate.setSeconds(0);
		targetDate.setMilliseconds(0);
		var targetDateStr = param ? param : targetDate.toString();
		var nTime = Date.parse(targetDateStr);
		if(!isNaN(nTime)) targetDate.setTime(nTime);
		else if(!isNaN(targetDateStr)) targetDate.setTime(targetDateStr);
		if(first) targetDate.setDate(1);
		return targetDate;
	}
};


// Calendar Control
config.macros.viewCalendarControl = {
	handler: function(place,macroName,params) {
		var targetDate = config.macros.viewCalendar.getTargetDate(params[0],false);
		var theTable = createTiddlyElement(place, "table");
		var theTableBody = createTiddlyElement(theTable, "tbody");
		var theTableRecord = createTiddlyElement(theTableBody,"tr");
		var theElement = createTiddlyElement(theTableRecord,"td");
		theElement.align = "right";
		createTiddlyButton(theElement,"<","previous month",this.goPrev);
		theElement = createTiddlyElement(theTableRecord,"td");
		theElement.id = "idNowDate";
		theElement.align = "center";
		createTiddlyButton(theElement,targetDate.formatString("YYYY/0MM"),targetDate.formatString("YYYY/0MM/0DD"),this.goToday);
		theElement = createTiddlyElement(theTableRecord,"td");
		theElement.align = "left";
		createTiddlyButton(theElement,">","next month",this.goNext);
		theTableRecord = createTiddlyElement(theTableBody,"tr");
		theElement = createTiddlyElement(theTableRecord,"td");
		theElement.id = "idMainCalendar";
		theElement.setAttribute("colSpan",3);
		config.macros.viewCalendar.handler(theElement,macroName,params);
	},

	goPrev: function() {
		var theTable = null;
		if(this.parentElement) theTable = this.parentElement.parentElement.parentElement;
		else if(this.parentNode) theTable = this.parentNode.parentNode.parentNode;
		var theMonth = theTable.childNodes[0].childNodes[1];
		if(theMonth.innerText) theMonth = theMonth.innerText;
		else if(theMonth.textContent) theMonth = theMonth.textContent;
		// prev month
		var nowFirst = config.macros.viewCalendar.getTargetDate(theMonth + "/01",false);
		var nMonth = nowFirst.getMonth();
		if(nMonth) {
			nowFirst.setMonth(nMonth - 1);
		} else {
			nowYear = nowFirst.getYear();
			if(nowYear < 1000) nowYear += 1900;
			nowFirst.setYear(nowYear - 1);
			nowFirst.setMonth(11);
		}
		return config.macros.viewCalendarControl.goTarget(theTable, nowFirst);
	},

	goToday: function() {
		var theTable = null;
		if(this.parentElement) theTable = this.parentElement.parentElement.parentElement;
		else if(this.parentNode) theTable = this.parentNode.parentNode.parentNode;
		var theMonth = theTable.childNodes[0].childNodes[1].childNodes[0];
		// today
		var nowFirst = config.macros.viewCalendar.getTargetDate(theMonth.getAttribute("title"),true);
		return config.macros.viewCalendarControl.goTarget(theTable, nowFirst);
	},

	goNext: function() {
		var theTable = null;
		if(this.parentElement) theTable = this.parentElement.parentElement.parentElement;
		else if(this.parentNode) theTable = this.parentNode.parentNode.parentNode;
		var theMonth = theTable.childNodes[0].childNodes[1];
		if(theMonth.innerText) theMonth = theMonth.innerText;
		else if(theMonth.textContent) theMonth = theMonth.textContent;
		// next month
		var nowFirst = config.macros.viewCalendar.getTargetDate(theMonth + "/01",false);
		var nMonth = nowFirst.getMonth();
		if(nMonth != 11) {
			nowFirst.setMonth(nMonth + 1);
		} else {
			nowYear = nowFirst.getYear();
			if(nowYear < 1000) nowYear += 1900;
			nowFirst.setYear(nowYear + 1);
			nowFirst.setMonth(0);
		}
		return config.macros.viewCalendarControl.goTarget(theTable, nowFirst);
	},

	goTarget: function(theTable, target) {
		// get month control
		var theMonth = theTable.childNodes[0].childNodes[1];
		// get calendar control
		var theCalendarP = theTable.childNodes[1].childNodes[0];
		var theCalendar = theCalendarP.childNodes[0];

		// month
		if(theMonth.childNodes[0].innerText) theMonth.childNodes[0].innerText = target.formatString("YYYY/0MM");
		else if(theMonth.childNodes[0].textContent) theMonth.childNodes[0].textContent = target.formatString("YYYY/0MM");
		// calendar
		var paraLen = theCalendar.getAttribute("paraLen");
		var params = new Array(paraLen);
		for(i = 0; i < paraLen; i++) {
			params[i] = theCalendar.getAttribute("para"+i);
		}
		params[0] = target.formatString("YYYY/0MM/0DD");
		theCalendarP.innerHTML = "";
		config.macros.viewCalendar.handler(theCalendarP,"viewCalendarControl",params);
		return false;
	}
};

//}}}