`(Hello ,world)

ツッコミ、添削大歓迎です。いろいろ教えてください。

2010-08-11

Opera...

テキストエリアでオートインデントさせるのに、JavaScriptであれこれ書いてる。動作確認は、IEははなから切り捨ててChromeFireFoxで主に試してる。一応動いて、Operaでも試してみるかとやってみると、挙動が全然違う。

RETを押したときにonkeydownでfalseを返してもRETが挿入される
改行
  • テキストエリア内に "\n" を突っ込むとChromeFireFoxでは10の1文字なのに、Opera だと[13, 10] の2文字になる?カーソル位置を計算できない…
選択範囲のセット
  • カーソル位置を移動させるのにテキストエリアの選択範囲のセットを使うが、なぜかひとつ前の位置になってしまう。+1してやらないといけない。

いろいろ、クロスブラウザめんどい…

閉じ括弧で対応範囲をハイライト

Lispの場合オートインデントが必要というよりは、閉じ括弧を入力したときに対応する開き括弧の位置を示してくれないとまともに使えないと個人的には思う。xyzzyなどでは対応する開き括弧の位置に一定時間ポイントが移って、また戻るようになっている。同じような機能をテキストエリアに組み込んでみる。

テスト (jsソース

up_list_backward()だかgoto_matched_open()で開き括弧の位置を取れるようにしたので、その範囲をtextarea.setSelectRange()で選択してやる。setTimeout()で一定時間が経過したり、その間になにかキーが押されたら、その選択ははずす。

keydownなどのイベントで、jQueryを使ったほうがクロスブラウザで楽かな、と思って使ってみた。

  • たくさん入力してスクロールするときになってもしてくれない。textarea.setSelectRange()でカーソル位置を設定しても自動的にはスクロールされない。どうやってやったらいいんだろう?
// 閉じ括弧の処理
//	対応する括弧があればその位置を、
//	なければ false を返す
var lisp_electric_close = function(target) {
	target.focus();
	var pos = getAreaRange(target);
	var text = target.value;
	var uppos = up_list_backward(text, pos.start);
	if (uppos === false)	return false;

	target.value = target.value.slice(0, pos.start) + ')' + target.value.slice(pos.end);
	set_flash_range(target, uppos, pos.start + 1);
	return uppos;
};

var $flash_timer;
var reset_flash = function(target) {
	if ($flash_timer) {
		clearTimeout($flash_timer);
		$flash_timer = null;
		var pos = getAreaRange(target);
		move_to(target, pos.end);
	}
}
var set_flash_range = function(target, start, end) {
	reset_flash(target);
	target.setSelectionRange(start, end);
	$flash_timer = setTimeout(function() {reset_flash(target)}, $flash_millisec);
};
トラックバック - http://cadr.g.hatena.ne.jp/mokehehe/20100811