こまったねー。
例えば、divにclickとdblclickを両方割り当てた場合、「トンッ、トントン!」とクリックとダブルクリックを発生させた場合
- Firefox/Google Chromeだと「トントン」で2クリックが発生
- IEだと「トントン」では1クリックしか発生しない
なんて動きになってる。以下検証に使ったコード。
<html>
<head>
<script type="text/javascript">
(function() {
var reg = function(e, t, f) {
if (window.attachEvent)
e.attachEvent('on'+t, f);
else
e.addEventListener(t, f, false);
};
reg(window, 'load', function(e) {
var c1 = 0, c2 = 0;
var panel = document.getElementById('click-panel');
var updateStatus = function() {
panel.innerHTML = "click:" + c1 + " dblclick:" + c2;
};
reg(panel, 'click', function() { c1++; updateStatus() });
reg(panel, 'dblclick', function() { c2++; updateStatus() });
reg(panel, 'mouseout', function() { c1 = c2 = 0; updateStatus() });
updateStatus();
});
})();
</script>
</head>
<body>
<div id="click-panel" style="background: blue; width: 600; height: 300"></div>
<body>
</html>
例えば、図を描きたい場合にクリックで多角形を描き、ダブルクリックで完了なんてユーザインタフェースは良くある話。
上の例で言えば
- Firefox/Google Chromeは「click:3 dblclick:1」
- IEだとは「click:2 dblclick:1」
なにそれ。前回クリックした時の(new Date).getTime()覚えておいて一定間隔以上でクリック発生...なんてコード、簡単だけど書きたくないよ。(ノД`)ウワーン
書いたといっても結構前からあったのですが、いらん所を削ぎ落として軽量Webサーバとして仕立て上げました。
軽量とは言えど、CGIを使って結構色々動きます。
例えば、ソースアーカイブを解凍したらCGIがあって、apacheから見える場所にコピーして...とか面倒くさかったりしますよね。
おれは今すぐWebサーバを起動したいんだ!そして今いるディレクトリのファイルをWebサーバからサーブしたいんだー!
って事ないですか?blogソフトウェアをダウンロードして今すぐ試したいけど、apacheインストールされてなかった...とか悲しすぎます。
今回紹介する"tinytinyhttpd"(tthttpd)はそんな、小さい様で大きな問題を解決出来るかもしれないソフトウェアです。
mattn's tinytinyhttpd at master - GitHub
tiny tiny httpd
http://github.com/mattn/tinytinyhttpd/tree/master
リンク先に、動いてる様子のキャプチャがあります。
ソースはC++で書いてます。WindowsとUNIX(Linuxでだけ動作確認)で動作します。
機能としては、マルチスレッドサーバ、カスタマイズ、ディレクトリスティング、CGI起動が可能です。
小ささをウリにしているのでインストールとか、レジストリとか、面倒くさいものは要りません。exeファイルだけあれば起動します。
一応、設定ファイルの記述も可能で
[global]
port=8080
root=c:/temp/mtos
indexpages=index.html,index.php
charset=cp932
[mime/types]
cgi=@c:/strawberry/perl/bin/perl.exe
php=@c:/progra~1/php/php-cgi.exe
という設定ファイルを"-c"オプションで指定する事も出来ます。デフォルトではポート8080番でカレントディレクトリをドキュメントルートとし、phpとperlが適当なパスでCGI起動される様になっています(パスが違う場合は設定ファイルから変更出来ますし、拡張子rbに対してrubyを追加する事も出来ます)。
私が試した限りですが、以下のソフトウェアの動作が確認出来ています。
- MTOS(Movable Type Open Source) (perl)
- WordPress (php)
- blogn Plus (php)
- tDiary (ruby)
- PukiWiki (php)
- NucreusCMS (php)
- blosxom (perl)
などなど。CGIで動くならば大体動きます。
ライセンスはBSDライセンスとします。使ってみて下さい。
コードはgithubにあるので、patchウェルカムです。
今後は、コードのブラッシュアップと、拡張なんかを考えて行きたいなーと思ってます。
miyagawaさんのAnyEvent::Twitter::Streamを使って「NullPointerException」をtrackして「Ga!!」を返信するスクリプトを書いてみた。trackにマルチバイトが使えないのが残念。「がっ!!」にしても良いけど、出来れば欧米の方達にも反応したい。
#!/usr/bin/perl
use strict;
use warnings;
use Config::Pit;
use AnyEvent::Twitter::Stream;
use Net::Twitter::Lite;
binmode STDOUT, ":utf8";
my $config = pit_get("nullpo-ga", require => {
"username" => "your username on twitter.com",
"password" => "your password on twitter.com"
});
my $nt = Net::Twitter::Lite->new(
username => $config->{username},
password => $config->{password},
);
my $done = AnyEvent->condvar;
my $streamer = AnyEvent::Twitter::Stream->new(
username => $config->{username},
password => $config->{password},
method => "track",
( track => 'NullPointerException' ),
on_tweet => sub {
my $tweet = shift;
print "$tweet->{user}{screen_name}: $tweet->{text}\n";
eval { $nt->update("\@$tweet->{user}{screen_name} Ga!!") };
},
on_error => sub {
my $error = shift;
warn "ERROR: $error";
$done->send;
},
on_eof => sub {
$done->send;
},
);
$done->recv;
追記
miyagawaさんから返信のupdateでブロックしちゃうのでAnyEvent::Twitter使えば良いと教えて貰いました。
#!/usr/bin/perl
use strict;
use warnings;
use Config::Pit;
use AnyEvent::Twitter;
use AnyEvent::Twitter::Stream;
binmode STDOUT, ":utf8";
my $config = pit_get("nullpo-ga", require => {
"username" => "your username on twitter.com",
"password" => "your password on twitter.com"
}
);
my $done = AnyEvent->condvar;
my $twitty = AnyEvent::Twitter->new(
username => $config->{username},
password => $config->{password},
);
my $streamer = AnyEvent::Twitter::Stream->new(
username => $config->{username},
password => $config->{password},
method => "track",
( track => 'NullPointerException' ),
on_tweet => sub {
my $tweet = shift;
print "$tweet->{user}{screen_name}: $tweet->{text}\n";
$twitty->update_status("\@$tweet->{user}{screen_name} Ga!!", sub {
my ($twitty, $status, $js_status, $error) = @_;
if (defined $error) {
warn "ERROR: $error";
}
}
);
},
on_error => sub {
my $error = shift;
warn "ERROR: $error";
$done->send;
},
on_eof => sub {
$done->send;
},
);
$done->recv;