2010.01.28 Thursday | 17:36

  ふきだし透過画像+相対位置のテスト プログラマ

JavaScript : クリックした要素の位置を計算して、近くにウインドウを開くIE6対応の背景透過PNG用javaScript ライブラリ の合成テスト。



※ ライブラリ化する前の動作確認。



<script
	type="text/javascript"
	src="http://winofsql.jp/lightbox_ie6png.js"
></script>
<script type="text/javascript">
function setWin(target,x,y,w,h) {
	var numY = target.offsetTop;
	var numX = target.offsetLeft;
	var obj = target;
	while( obj = obj.offsetParent ) {
		numY += obj.offsetTop;
		numX += obj.offsetLeft;
		if ( obj.tagName == 'BODY' ) {
			break;
		}
	}
	document.getElementById("win_base").style.top = (numY+y) + "px";
	document.getElementById("win_base").style.left = (numX+x) + "px";
	document.getElementById("win_base").style.width = w + "px";
	document.getElementById("win_base").style.height = h + "px";
	document.getElementById("win_base").style.display = "";
}
</script>
<div
	id="win_base"
	style='
		position: absolute;
		display: none;
		color: black;
		width:0px;
		height:0px;
		z-index:1000;
	'
	onClick='event.cancelBubble = true;'>
	<input
		type="image"
		src="http://winofsql.jp/image/mcancel.png"
		style='float:right;'
		onClick='this.parentNode.style.display = "none";'
	>
	<div id=win_box style='padding:2px;'>
<script type="text/javascript">
var ar = {
	url: "http://winofsql.jp/image/fd01.png",
	width: 150,
	height: 100,
	x: 0,
	y: 0
}
lightbox_ie6png.load(ar);
var ar = {
	text: "<span style='font-size:12px;'>こんにちは</span>",
	x: 40,
	y: 70 
}
lightbox_ie6png.loadtext(ar);
</script>
	</div>
</div>
<input
	type="button"
	value="test"
	onClick='setWin(this,-15,-16,150,100)'
>






2010.01.10 Sunday | 18:47

  もう既におもいっきりプログラムの書ける技術者にとってのRuby の憂鬱... (1) プログラマ

Ruby はいわゆる文法的にまとめられた文書では役に立たないですね。
入門書的なものをひろげられても、「だからどーした」ってなります。

何が必要かというと、外国に行った時に「すぐ役にに立つ日常会話」でして、
その場面場面で、「辞書」引いてたんでは間に合わないわけですよ。
時には、みつからないで意思をとうとう直接伝えられず、ジェスチャーで
なんとか対症療法したなんてのがしょっちゅうです。

元々企業が作ったものでは無いですから、文書が不完全なのは当たり前で、
これは自分の作ったソフトのドキュメントを作る時の苦しさを考えたら


めちゃめちゃ「納得」


Mechanize なきゃ、絶対無視して通ったはずなのですが・・・これ、とってもおいしい禁断の果実ですし:-))

で、まず最初に覚える事。

1) 改行は LF である事。
2) 先頭は以下がほぼ鉄板( キャラクタセットは適宜 )
#!/usr/local/bin/ruby
print "Content-Type: text/html; Charset=utf-8\n\n";

# 標準エラー出力の出力先を標準出力に変更
$stderr = $stdout









2010.01.03 Sunday | 20:35

  Yahoo UI ポップアップカレンダー プログラマ







<link rel="stylesheet" type="text/css" href="http://lightbox.on.coocan.jp/yui/build/fonts/fonts-min.css" />
<link rel="stylesheet" type="text/css" href="http://lightbox.on.coocan.jp/yui/build/button/assets/skins/sam/button.css" />
<link rel="stylesheet" type="text/css" href="http://lightbox.on.coocan.jp/yui/build/container/assets/skins/sam/container.css" />
<link rel="stylesheet" type="text/css" href="http://lightbox.on.coocan.jp/yui/build/calendar/assets/skins/sam/calendar.css" />
<script type="text/javascript" src="http://lightbox.on.coocan.jp/yui/build/yahoo-dom-event/yahoo-dom-event.js"></script>
<script type="text/javascript" src="http://lightbox.on.coocan.jp/yui/build/dragdrop/dragdrop-min.js"></script>
<script type="text/javascript" src="http://lightbox.on.coocan.jp/yui/build/element/element-min.js"></script>
<script type="text/javascript" src="http://lightbox.on.coocan.jp/yui/build/button/button-min.js"></script>
<script type="text/javascript" src="http://lightbox.on.coocan.jp/yui/build/container/container-min.js"></script>
<script type="text/javascript" src="http://lightbox.on.coocan.jp/yui/build/calendar/calendar-min.js"></script>

<link rel="stylesheet" type="text/css" href="http://lightbox.on.coocan.jp/yui/cal.css" />

<script type="text/javascript">

document.body.className = document.body.className + " yui-skin-sam";
YAHOO.util.Event.onDOMReady(function(){

	var Event = YAHOO.util.Event,
		Dom = YAHOO.util.Dom,
		dialog,
		calendar;

	var showBtn = Dom.get("show");

	Event.on(showBtn, "click", function() {

		if (!dialog) {

			Event.on(document, "click", function(e) {
				var el = Event.getTarget(e);
				var dialogEl = dialog.element;
				if (el != dialogEl && !Dom.isAncestor(dialogEl, el) && el != showBtn && !Dom.isAncestor(showBtn, el)) {
					dialog.hide();
				}
			});

			function resetHandler() {
				var selDates = calendar.getSelectedDates();
				var resetDate;
		
				if (selDates.length > 0) {
				resetDate = selDates[0];
				} else {
				resetDate = calendar.today;
				}
		
				calendar.cfg.setProperty("pagedate", resetDate);
				calendar.render();
			}
		
			function closeHandler() {
				dialog.hide();
			}

			dialog = new YAHOO.widget.Dialog("container", {
				visible:false,
				context:["show", "tl", "bl"],
				buttons:[ {text:"Reset", handler: resetHandler, isDefault:true}, {text:"Close", handler: closeHandler}],
				draggable:false,
				close:true
			});
			dialog.setHeader('\u65e5\u4ed8\u3092\u9078\u629e\u3057\u3066\u4e0b\u3055\u3044');
			dialog.setBody('<div id="cal"></div>');
			dialog.render(document.body);

			// カレンダーが表示される時の初期処理
			// ※ 現在の値でカレンダーを選択する
			dialog.showEvent.subscribe(function() {
				var str = document.getElementById("date").value;
				var dt = new Date(str);
				if ( !isNaN(dt) ) {
					calendar.cfg.setProperty('selected', str);
					calendar.cfg.setProperty('pagedate', dt, true);
					calendar.render();
				
					if (YAHOO.env.ua.ie) {
				
						dialog.fireEvent("changeContent");
				
				
					}

				}
			});

		}

		if (!calendar) {

			calendar = new YAHOO.widget.Calendar("cal", {
				iframe:false,	  // Turn iframe off, since container has iframe support.
				hide_blank_weeks:true  // Enable, to demonstrate how we handle changing height, using changeContent
			});

			calendar.cfg.setProperty("MDY_YEAR_POSITION", 1);
			calendar.cfg.setProperty("MDY_MONTH_POSITION", 2);
			calendar.cfg.setProperty("MDY_DAY_POSITION", 3);

			calendar.cfg.setProperty("MY_YEAR_POSITION", 1);
			calendar.cfg.setProperty("MY_MONTH_POSITION", 2);

			// Date labels for Japanese locale

			calendar.cfg.setProperty("MONTHS_SHORT",   ["01", "02", "03", "04", "05", "06", "07", "08", "09", "10", "11", "12"]);
			calendar.cfg.setProperty("MONTHS_LONG",	["1\u6708", "2\u6708", "3\u6708", "4\u6708", "5\u6708", "6\u6708", "7\u6708", "8\u6708", "9\u6708", "10\u6708", "11\u6708", "12\u6708"]);
			calendar.cfg.setProperty("WEEKDAYS_1CHAR", ["\u65E5", "\u6708", "\u706B", "\u6C34", "\u6728", "\u91D1", "\u571F"]);
			calendar.cfg.setProperty("WEEKDAYS_SHORT", ["\u65E5", "\u6708", "\u706B", "\u6C34", "\u6728", "\u91D1", "\u571F"]);
			calendar.cfg.setProperty("WEEKDAYS_MEDIUM",["\u65E5", "\u6708", "\u706B", "\u6C34", "\u6728", "\u91D1", "\u571F"]);
			calendar.cfg.setProperty("WEEKDAYS_LONG",  ["\u65E5", "\u6708", "\u706B", "\u6C34", "\u6728", "\u91D1", "\u571F"]);

			// Month/Year label format for Japan
			calendar.cfg.setProperty("MY_LABEL_YEAR_POSITION",  1);
			calendar.cfg.setProperty("MY_LABEL_MONTH_POSITION",  2);
			calendar.cfg.setProperty("MY_LABEL_YEAR_SUFFIX",  "\u5E74");
			calendar.cfg.setProperty("MY_LABEL_MONTH_SUFFIX",  "");

			calendar.render();

			calendar.selectEvent.subscribe(function() {
				if (calendar.getSelectedDates().length > 0) {

				var selDate = calendar.getSelectedDates()[0];

				// Pretty Date Output, using Calendar's Locale values: Friday, 8 February 2008
				var wStr = calendar.cfg.getProperty("WEEKDAYS_LONG")[selDate.getDay()];
				var dStr = selDate.getDate() + "";
				if ( dStr.length == 1 ) {
					dStr = "0" + dStr;
				}
				var mStr = calendar.cfg.getProperty("MONTHS_SHORT")[selDate.getMonth()];
				var yStr = selDate.getFullYear();
		
				Dom.get("date").value = yStr+ "/" + mStr + "/" + dStr;
				} else {
				Dom.get("date").value = "";
				}
				dialog.hide();
			});

			calendar.renderEvent.subscribe(function() {
				// Tell Dialog it's contents have changed, which allows 
				// container to redraw the underlay (for IE6/Safari2)
				dialog.fireEvent("changeContent");
			});
		}

		var seldate = calendar.getSelectedDates();

		if (seldate.length > 0) {
			calendar.cfg.setProperty("pagedate", seldate[0]);
			calendar.render();
		}

		dialog.show();
	});
});
</script>

<div class="box">
<div class="datefield">
	  <label for="date">Date: </label><input type="text" id="date" name="date" value="" /><button type="button" id="show" title="Show Calendar"><img src="http://lightbox.on.coocan.jp/yui/assets/calbtn.gif" width="18" height="18" alt="Calendar" ></button>
</div>
</div>
Yahoo UI でカレンダーフィールドは結構面倒です
上記コードは日本語用にチューニングしています。
cal.css は、サンプルコードから取りだしたものですが必要です

document.body.className = document.body.className + " yui-skin-sam";

で、動的に BODY にクラスを追加しています。
( これも必要です )

実際に使うにはもうすこしコードチューニングが必要で
カレンダーダイアログを開く時に、フィールドの日付
を採用する必要があります
dialog.showEvent.subscribe(function() {

	calendar.cfg.setProperty('selected', '2009/2/5');
	calendar.cfg.setProperty('pagedate', new Date('2009/2/5'), true);
	calendar.render();

	if (YAHOO.env.ua.ie) {

		dialog.fireEvent("changeContent");


	}
});




2010.01.03 Sunday | 11:57

  ブックマークレット : 手書きブログのタイトルにURLが書かれている場合にそこへ移動する プログラマ

複雑な処理を行うブックマークレットは、単独では文字数制限があるので、
外部の .js ファイルに委ねます。

ページの中から、BlogTitlePane というクラスを持つ DIV を探して、
見つけたら、その中が http で始まっているかを確認して、確認の上移動します。
※ コメントにしてある部分は、新しいウインドウで開く方法です

以下はコードの本体です。
if (!window.lightbox_tjump) {
(
function() {
	window.lightbox_tjump = 
	{
		version: 1.01
		,
		init : function( ) {
			var target = document.getElementsByTagName("DIV");
			var count = target.length;
			var i,work;
			for( i = 0; i < count; i++ ) {
				work = target[i].className + "";
				work = work.toUpperCase();
				if ( work == "BLOGTITLEPANE" ) {
					if ( (target[i].innerHTML).substr(0,4) == 'http' ) {
						if ( confirm(target[i].innerHTML) ) {
							window.location = target[i].innerHTML;
						}
//						window.open(target[i].innerHTML);
					}
					break;
				}
			}
		}
	};
}
)();
}

lightbox_tjump は、ほぼユニークであればいいタイトルのようなもので、
window オブジェクトのプロパティに処理を埋め込む方法です。
ブックマークレツトはその特性上、同時に複数のものを実行する事は無い
ので極端な話、lightbox_tjump は常に同じでも問題は無いと思います。

ただ、管理上は別にしておいたほうが良いとは思いますが。

ブックマークレットの埋め込みはこのユニーク名とURL以外はほぼ一定です。
▼ ブックマークレットの登録
手書きブログタイトルジャンプ
<a href="javascript:var mylib=document.createElement('script');if(!window.lightbox_tjump){mylib.setAttribute('src','http://winofsql.jp/tegaki_tjump.js');document.body.appendChild(mylib);(function(){if(window.lightbox_tjump){lightbox_tjump.init();}else{setTimeout(arguments.callee);}})();}else{lightbox_tjump.init();}void(mylib);"onclick='	if (window.navigator.appName.toLowerCase().indexOf("microsoft") > -1) {		event.returnValue = false;		alert("右クリックしてポップアップメニューからお気に入りに追加して下さい   ");	}	else {		event.preventDefault();		alert("右クリックしてポップアップメニューからブックマークして下さい   ");	}'>手書きブログタイトルジャンプ</a>





1/1