2009年2月25日水曜日

キーボードブラウジングについて

このエントリーをはてなブックマークに追加
昨晩、というか、本日未明にSafari4に関してざくっと書いたらtwitterでforestkさんから

キーボードブラウジングって例えば?

って聞かれたので、ここにごりっと書こうと思います。

キーボードブラウジングとは、キーボード操作でブラウジングする事と定義します。
(日本語的におかしいけど気にしないっ!)
超頑張れば、どのブラウザでもキーボード操作でブラウジングできるのですが、超頑張りたくないんです、ものぐさなので。
ただ、それだったらどの程度までの操作だったら面倒じゃないって感じるんだよ、ボケぇって突っ込まれそうなので、面倒くさくない操作を羅列。
ポイントは三点。

 ○hjklでの移動
  出来れば、jkhlでページの上下左右のスクロールが出来るようにして欲しい。
  デフォルトだと、矢印キーがそれにあたるのかなぁ。
  でも、それって結構面倒だって感じるようになってきた昨今。
  えぇ、単なるvim指病です。
 ○楽々ターゲット選択
  楽々とか書いたけど、要はHit a Hintおよび空間ナビゲーションの事。
  以下、Safariでどうやるか。
  ■Hit a Hintは既にedvakfさんがブックマークレット化してくれているので、それを流用すればなんとかなりそう。
  ■空間ナビゲーションはOpera以外搭載が皆無なので、不可能。UserJSでどうこうやろうって思えるレベルの挙動じゃないし。(頑張れば出来る?)
  ■現実解としては、UserJavaScript+Hit a Hint改造版?
  妄想はともかく、マウス触ってクリックって動作をなるべくしたくないんです。
  これが、楽々ターゲット選択の最大の理由。
 ○1キーでのタブ切換(ホームポジションを崩さずに切換)
  タブブラウザでは、タブ切換えに一番神経を使う、と思っている。その点、OperaとVimperatorはタブ切換を1キーで行う事が出来る。
  (1,2がOperaでHLがVimp。もっとも、Vimpは1キーじゃないけど、_vimperatorrcを書き換えれば、1キー切換えできる)
  これは地味に大切なポイントで、「タブ切換だったら、Ctrl+Tab|Ctrl+Shift+Tabで出来るじゃん」って意見は却下。
  実際にやって見れば分かるけれども、指、つります。
  余談ですが、エクセルのタブ切換はCtrl+PageUp/PageDownで、これもかなり指がつる。
  ってか、僕のキーボードはHHKだから、Fnキーと組み合わせないと出来ないんだよ、F*ck!
  閑話休題。
  僕の環境は無視したとして、なるべくホームポジションから移動せずにタブとか切換たいんです。
  要するに、超ものぐさなんですよ、僕は。

総括すると”マウス触りたくないにゃん/ホームポジション好きだわん“ってだけなんです。
#語尾きめえぇ<セルフ突っ込み乙


Safariでも矢印キーとTabとCtrlとShiftとAltとEnterといくつかの英数字キーと記号キーとファンクションキーを駆使すれば何とかキーボードで操作できます。
でもね。
空いている英数字キーがいっぱいあるんですよ。
もっとそれを有効活用したいじゃないですか。
ブラウジングって本来ならマウス主体の操作が、キーボード主体になった瞬間二倍くらい効率アップしたりするかもしれないじゃないですか。
そういった変態じみた願望がキーボードブラウジングの根底にあるのかなぁと。


teramakoさんってすっげえぇ人が「CUIとGUIの融合に興味津々」ってキャッチコピー使っていますけれど、多分CUIってのはインプットで、GUIってのはアウトプットなのかなぁと勝手に思っています。
コマンドベースのインプットでグラフィカルなアウトプットを操作する。
それって、結構カッコ良いなぁって思うし、何より速いと思うんです。
ma.laさんってやっぱり超すっげぇ人が、速さ=正しいUIって提言していましたっけ、どこかで。
僕は、速さ=正しいとは思いませんが、速さ=素晴らしいと思っています。
なので、マウスよりも若干速く操作できるキーボードブラウジングが僕は好きなんです。
(若干ってのは謙遜で、自分的には500倍くらい速い。脳内補完では)
それをデフォルトで提供してくれるブラウジング環境のOperaが好きなんです。

長々と駄文失礼しましたー。

safari4

このエントリーをはてなブックマークに追加
Safari4のPublic Beta版を入れてみました。
スクリーンショットはこんな感じ


最初はフォントの文字化けが酷かったんだけど、勘でVL P Gothicを選んで再起動したら日本語とかちゃんと表示されるようになった。
勇者は試してみてください。
速度面は正直どれだけ速いか体感では分からないくらい。もう差が殆どないと言っても過言ではない。
タブバーの表示位置と、カスタマイズボタンがChromeの真似になっているけど、それだけUIとしてChromeが優れていた証拠だろうね。
ただ、デザイン的にはSafari4のタブバーに惚れた。
後はキーボードブラウジングが出来るようになれば、迷わずSafariへ乗り換えるだろうなぁ。
ってか、Operaもタブバーをウインドウ部分に表示したらカッコ良くなると思う。
Firefoxのアドオンとかでその辺ぱくるのが出てくるのを楽しみにしてる(^^)

2009年2月24日火曜日

sqlite3の罠

このエントリーをはてなブックマークに追加
sqliteアップデートしてーなーと思って、公式から(特に何も考えずに)sqlite3.6.10を落としてcheckinstallでrpm作ってインストールした。

それからyumが急に動かなくなるという面白現象発生。
具体的には、
Can not create packages table: near "release": syntax error
というエラーが出る。正直意味不明。
ぐるぐる回ってようやくヒントらしきものをゲット。
https://bugzilla.redhat.com/show_bug.cgi?id=481189


This is sqlite bug alright, see
http://www.mail-archive.com/sqlite-users@sqlite.org/msg39666.html

My bad (insufficient testing), apologies. Will fix right away.


バグですかwwww
swwwqwwwlwwwiwwwtwwwewww3wwww

盛大に吹いた。
sqlite3.6.11を入れたら無事に動いた。
まさかsqlite3とyumでこんなにはまるとは思っていなかったなぁ。

2009年2月20日金曜日

A bit bad RTM for operaを書いたよー。

このエントリーをはてなブックマークに追加


A bit better rtmというgreasemonkeyがあって、この間Opera用に書き換えたんだけど、やっぱり自分流にカスタマイズしたくなったので書き換えた。
名づけて、A bit bad RTM for Opera。

最も、殆どコピペで作っているので、あんまり意味は無いかも(笑)

・機能
 ・RTMのタスクリストを画面左側に表示します
 ・Shift+J、Kでタスクリストを上下に移動できます
 ・1、2、3で優先順位を変更していたのを、q、w、eで変更できるようにしました。
 ・1キーと2キーはタブ切換えの為に機能を殺してあります。(ワンキーショートカットユーザならば常識)

ほんのちょっとだけ楽に操作したいという気持ちで書いているので、正直機能はしょぼいです。

コードライセンスは元のコードのライセンスに従います。
CodeReposとgithubにアップしました。

CodeRepos
http://coderepos.org/share/browser/lang/javascript/userscripts/a_bit_bad_rtm_for_opera.user.js

GitHub
http://github.com/ArcCosine/userscript/tree/master

Operaユーザの人は是非使ってみてください。
Firefoxユーザの人は素直にA Bit Better RTMを使いましょう(笑)

2009年2月17日火曜日

「手紙」を読んで、差別について持論をぶちまけたいのっ!!

このエントリーをはてなブックマークに追加
本エントリは、東野圭吾作「手紙」についてのネタバレ含みます。あしからず。











東野圭吾作の「手紙」を読みました。
読書メータに辛らつなコメントを残すほど、僕はこの話が嫌いです。

あらすじとしては、強盗殺人を犯してしまった兄を持つ弟のその後の人生を淡々とつづっています。
兄と弟を繋ぐのは、毎月送られてくる兄の「手紙」
塀の中にいる兄の手紙は他愛の無い内容で、安穏とした暮らしを伺わせる。
一方塀の外にいる弟は負の財産を背負ったまま賢明に生きようとするが常にどこかで、強盗殺人の弟というレッテルを貼られ、破綻する。
そしてある日終に、弟は決意をして兄に「手紙」を書くことにした。

ざっと書くとこんな感じです。

以下ネタバレ

最終的に、弟は兄の縁を切る事を宣言した手紙を送る。
それにより、兄は自らがどれだけ弟に負担をかけていたのかという事に気づき、自戒の念に苦悩する。
僕自身の誤解が無ければ、この事で涙した人が多いのかもしれない。

正直、反吐が出るほど出来すぎた、作者に都合の良い理論だなと思った。
殺人者が持つ後悔の念をあまりにも軽薄に扱っていると僕は感じた。
間違いなく、東野圭吾は殺人をした事が無い(そもそも、していたら問題だが)
そのくせ、安易に話が作りやすいからという理由で、ミステリを選んでると思う。
ミステリはもっと(略


閑話休題
この作品では、合法的差別という概念が説明されているし、差別の無い世界なんて無いと登場人物の口を借りて宣言までしている。
即ち、現在の世界を一方的に決め付けているのだ。
差別の無い世界は確かに存在する。子供たちの世界がそれだ。
差別を持ち込むのは間違いなく大人である。
大人だけで社会は構成されている訳ではない。しかし、東野視線ではそれしかないのだ。
汚い現実世界をまるで写真を見ているかのように描くことで自分がそこから離脱できていると考えているのかもしれない。
それはさすがに言いすぎだし、偏見が強いが、少なくとも東野圭吾は差別容認派である事をこの作品を通して語っている。
同時に、読者全員を自らと同じ立場であると決め込み、同じ精神構造を持っているだろう、お前たちも、と上から目線で物語を書いているのに腹が立ってしょうがなかった。
精神レベルの低さを自慢げに書いているようにしか思えないからだ。
読者を馬鹿にしていると感じるほど訴え方が稚拙だ。

読書メータに投稿したコメントに、「これで感動したという人は相当冷たい人」と一文を付け加えたのはまさにソレ。
感動は共感という感情の動きがあって初めて生まれる感情である。
何に共感したかによるが、兄だろうと弟だろうとおにゃのこだろうと、この作品に出てくる登場人物は全て東野圭吾の分身であり、差別容認を推薦する冷酷なキャラクターである。それに共感したアナタは、間違いなく冷酷な人だ。
自分が冷酷であるという事を頭の片隅でも考えられなかったなら、使い古された言葉ではあるが、想像力が欠けているのだろう。読解力が無いと言っても良い。

僕自身は俗に言う博愛主義者だ。最も、誰も彼も愛する事と誰も彼も愛さない事は選択しないという意味で同義であり、もしかしなくても僕は世界で一番冷酷な人間だと思う。
だからこそ余計にこの作品へ寄せられるコメントの数々に苛立ちを感じるのだろう。
この作品にそこまで価値あるって評価する事が理解できない。
それはつまり、僕がこの世界にまだ絶望してないからだと思う。
差別の無い世界は実現出来ると僕は信じているからだ。
でも、この作品を価値ある作品だと認めた人たちは、この世界に絶望し差別の無い世界なんか無いよなと自分の心に言い聞かせる事によりその立場に居ない自分に安堵するという安楽な道を選んでいる。
それが全く持って許せない。
僕は、差別される側に回るとしても、絶対に差別する側には回らない。
ここが、多分決定的に異なっている点だろう。
その決意があるからこそ、差別容認を推奨する「手紙」が許せないんだと思う。

「仕方ない」「みんなそうだから」「現実は違うよね」

どれもこれも、差別から逃げる言葉だと思う。
真正面から向き合わないのは楽だもんね。

これは完全な人生観なので、「そこまで真面目に考えるなよ、中二病乙www」といわれたらそれまでの駄文です。
ま、そういう考え方をする人もいるのか、変わっているなぁと思うのが大人の対応だと思いますよ?

まとめ
「手紙」は有害図書。うん。やっぱり、これくらい言わないとエントリ書いた意味が無いよね。


追記
Q「そういえば、ArcCosineさんはよく「IE○ね」ってPostしまくってるよね。アレは差別じゃないの?」
A「IEは人間じゃないので、差別対象には入りません。僕は人間博愛主義者で、プログラムは徹底的な差別主義者です」
Q「最低ですね」
A「はい、最低です」
Q「○ねば良いのに」
A「本当に、たまに自分は○んだ方が世のためじゃないかって思うことが良くあります」
Q「でも、○ぬ気は無いんですよね?」
A「ええ。○ぬのは怖いので」
Q「自己中?」
A「自己中。超自己中」
Q「胸がスカッとするくらい最低ですね」
A「はい。僕は最低人間です。もっと罵ってください。ハァハァ」
Q「帰れ」
A「\e」

2009年2月11日水曜日

自分用rubyメモ

このエントリーをはてなブックマークに追加
今日rubyを鯖にインストールしなおしたので、そのメモ。
今まで、yum install rubyみたいな軟弱なやり方だったけど、そろそろyumに頼るのはやめようかなぁとか思った。
時代はrpmだよねー!(どんだけ時代逆行してるんだ、お前は)
って事で、rpmじゃないとやだもん!って人用のメモ

流れ
・yumでインストールしたrubyパッケージを片っ端から削除
・Rubyインストール
 ・rubyソースダウンロード
 ・make
 ・rpm作成
 ・インストール
・gemインストール
 ・gemソースダウンロード
 ・rpm作成
 ・インストール
・mod_rubyインストール
 ・mod_rubyソースダウンロード
 ・make

うわ、書き出して超やる気なくした

ぐちってもしょうがないから一気に行くぞー!

・yumでインストールしたrubyパッケージを片っ端から削除

 コマンドはyum remove ruby ruby-libs
 多分これで全部削除できたはず
 後、gemとか上手く削除ってくれい。削除の仕方は知らないwww(ぉい)

・Rubyインストール

 ・rubyソースダウンロード
  今回は1.8.7p72を落とす。
  
wget http://core.ring.gr.jp/archives/lang/ruby/ruby-1.8.7-p72.tar.gz

 ・make
  
tar zxvf ruby-1.8.7-p72.tar.gz
cd ruby-1.8.7-p72
./configure --prefix=/usr
make

・rpm作成
  checkinstallは入ってるよねー?(ぉい)
  
checkinstall --fstrans=no

  パッケージタイプを聞かれたら、RPMを作るので、Rをタイプそれ以外はひたすらエンター
  ね、簡単でしょ?
 ・インストール
  
rpm -Uvh --nomd5 /usr/src/redhat/RPMS/i386/ruby-1.8.7-p72-1.i386.rpm

  ね、簡単でしょ?

・gemインストール

 ・gemソースダウンロード
  
wget http://rubyforge.org/frs/download.php/45905/rubygems-1.3.1.tgz

 ・rpm作成
  
tar zxvf rubygems-1.3.1.tgz
cd rubygems-1.3.1
checkinstall -R "ruby setup.rb"

 ・インストール
  
rpm -Uvh --nomd5 /usr/src/redhat/RPMS/i386/rubygems-1.3.1-1.i386.rpm

  ね、簡単でしょ?

・mod_rubyインストール

 ・mod_rubyソースダウンロード
  
wget http://www.modruby.net/archive/mod_ruby-1.3.0.tar.gz

 ・make
  
tar zxvf mod_ruby-1.3.0.tar.gz
cd mod_ruby-1.3.0
./configure.rb --with-apxs=/usr/sbin/apxs --with-apr-includes=/usr/include/apr-1
make
make install

  ね、簡単でしょ?

ふう、まとめるのに疲れたorz

てすと

このエントリーをはてなブックマークに追加
あぶり出し文字のテスト。ほげっちょほげっちょほげっちょ
ほげっちょほげっちょほげっちょほげっちょほげっちょほげっちょほげっちょほげっちょほげっちょほげっちょほげっちょほげっちょほげっちょほげっちょほげっちょほげっちょほげっちょほげっちょほげっちょほげっちょほげっちょほげっちょほげっちょほげっちょほげっちょほげっちょほげっちょほげっちょほげっちょほげっちょほげっちょほげっちょほげっちょほげっちょほげっちょほげっちょほげっちょほげっちょほげっちょほげっちょほげっちょほげっちょほげっちょほげっちょほげっちょほげっちょほげっちょほげっちょほげっちょほげっちょほげっちょほげっちょほげっちょほげっちょほげっちょほげっちょほげっちょほげっちょほげっちょほげっちょほげっちょほげっちょほげっちょほげっちょほげっちょほげっちょほげっちょほげっちょほげっちょほげっちょほげっちょほげっちょほげっちょほげっちょほげっちょほげっちょほげっちょほげっちょほげっちょほげっちょほげっちょほげっちょほげっちょほげっちょほげっちょほげっちょほげっちょほげっちょほげっちょほげっちょほげっちょほげっちょほげっちょほげっちょほげっちょほげっちょほげっちょほげっちょほげっちょほげっちょほげっちょほげっちょほげっちょほげっちょほげっちょほげっちょほげっちょほげっちょほげっちょほげっちょほげっちょほげっちょほげっちょほげっちょほげっちょほげっちょほげっちょほげっちょほげっちょほげっちょほげっちょほげっちょほげっちょほげっちょほげっちょほげっちょほげっちょほげっちょほげっちょほげっちょほげっちょほげっちょほげっちょほげっちょほげっちょほげっちょほげっちょほげっちょほげっちょほげっちょほげっちょほげっちょほげっちょほげっちょほげっちょほげっちょほげっちょほげっちょほげっちょほげっちょほげっちょほげっちょほげっちょほげっちょほげっちょほげっちょほげっちょほげっちょほげっちょほげっちょほげっちょほげっちょほげっちょほげっちょほげっちょほげっちょほげっちょほげっちょほげっちょほげっちょほげっちょほげっちょほげっちょほげっちょほげっちょほげっちょほげっちょほげっちょほげっちょほげっちょほげっちょほげっちょほげっちょほげっちょほげっちょほげっちょほげっちょほげっちょほげっちょほげっちょほげっちょほげっちょほげっちょほげっちょほげっちょほげっちょほげっちょほげっちょほげっちょほげっちょほげっちょほげっちょほげっちょほげっちょほげっちょほげっちょほげっちょほげっちょほげっちょほげっちょほげっちょほげっちょほげっちょほげっちょほげっちょほげっちょほげっちょほげっちょほげっちょほげっちょほげっちょほげっちょほげっちょほげっちょほげっちょほげっちょほげっちょほげっちょほげっちょほげっちょほげっちょほげっちょほげっちょほげっちょほげっちょほげっちょほげっちょほげっちょほげっちょほげっちょほげっちょほげっちょほげっちょほげっちょほげっちょほげっちょほげっちょほげっちょほげっちょほげっちょほげっちょほげっちょほげっちょほげっちょほげっちょほげっちょほげっちょほげっちょほげっちょほげっちょほげっちょほげっちょほげっちょほげっちょほげっちょほげっちょほげっちょほげっちょほげっちょほげっちょほげっちょほげっちょほげっちょほげっちょほげっちょほげっちょほげっちょほげっちょほげっちょほげっちょほげっちょほげっちょほげっちょほげっちょほげっちょほげっちょほげっちょほげっちょほげっちょほげっちょほげっちょほげっちょほげっちょほげっちょほげっちょほげっちょほげっちょほげっちょほげっちょほげっちょほげっちょほげっちょほげっちょほげっちょほげっちょほげっちょほげっちょほげっちょほげっちょほげっちょほげっちょほげっちょほげっちょほげっちょほげっちょほげっちょほげっちょほげっちょほげっちょほげっちょほげっちょ

ほげっちょのゲシュタルト崩壊発生中。

Vimのマルチバッファ

このエントリーをはてなブックマークに追加


Twitterでedvakfさんから
「マルチバッファを知らないのが許されるのは小学生までだよねー」
って言われていないんだけれども、マルチバッファって知らなかったから使ってみた。
ちょ、ナニコレ!!!!
イメージとしてはIEの履歴に近いものなのかも。
なるほど、これで次から次へと切り替えることによってタブ非表示でも一画面で頑張れるんですね。


正直感動した。

ひとまず、使い方としては:buffersでバッファ一覧を表示して、:[N]bufferで開きたいファイルが開ける。
例えば、:buffersで4番のファイルが開きたければ、:4bufferみたいな使い方をする。


知らない事をさくっと教えてくれる垣根の低さがTwitterの良い所だと勝手に決め付けた。
自らの無知をさらけ出せるので、変態じゃないと耐久できないという罠があるけど別に良いよね?

という事で、マルチバッファを使うとこんな事が出来るぜ、ハァハァという意見募集中。
#ハァハァしないものでも可

2009年2月7日土曜日

珈琲は好きですか?

このエントリーをはてなブックマークに追加
本日は本の紹介

僕は珈琲を割りと飲む方です。
インスタントとか缶コーヒーとか所謂こだわりの無い部類に属しますが、珈琲のあの香りは何ともいえません。
珈琲の香りによってリラックスを感じる人は多いようです。
ニューヨークに居る人々は特にその傾向が強く、言わばカフェイン中毒者ばかり。
彼らが日本に来たらその珈琲の貧弱さにF○ck!を二百回くらい叫ぶでしょう。

って感じの薀蓄を語れる本がコレ↓


ミステリですが、「アメリカ人が好きそうなミステリ」なので、犯人とかさっくり分かるし、ドキドキは少ないですけれど、珈琲に関する薀蓄がかなり多い。
これ一冊読むだけでも十分価値があります。

主人公が女性なので、男が読むと「へえ、女性ってこんな事考えてるのかへぇへぇへぇ」ってへぇボタンを押したくなる事間違いなし。
総合的に見て面白い本だと思います。
#あー、でもミステリ(特に本格)を好きな人には物足りなさ過ぎる
#重要な事なので、繰り返しました。

珈琲飲んでいる時にふと思ったのでこのエントリ書いてみました。

無理やり動かすっ!

このエントリーをはてなブックマークに追加
去年の記事なんだけどそこのUserJavascriptが素敵過ぎたので、しばらくRTMはFirefoxで使っていたけどそれってある意味負けじゃねとか思ったので、無理やりOperaで動かせないかやってみた。

で、さっきやって見たら、二行だけコードいじったら使えた(笑)
くそ、俺はアホか!(アホです)

・リストのタブを左に動かす
・カウントをリストに加える
・Shift + j/k でリストをスイッチする

使えるのは多分上の三機能。残りの機能は使えなかった気がするけど、別に良いや(超無責任)

2/7追記
/*-- 追記ここから --*/
元ネタのURL張っていなかったので、張ります
http://userscripts.org/scripts/show/32518
/*-- 追記ここまで --*/


って事で、以下コード。
ライセンスは配布元に従います。
Opera10αで確認済。
これを使って生じたいかなるエラーやバグにはArcCosineは対応できません。
自己責任でお使いください。


// ==UserScript==
// @name A Bit Better RTM
// @namespace http://www.rememberthemilk.com
// @description Small improvements for Remember The Milk: display list tabs to the left; display tasks count; GoTo & MoveTo list quickly;
// @include http://www.rememberthemilk.com/*
// @include https://www.rememberthemilk.com/*
// ==/UserScript==
//

window.wrappedJSObject = window.wrappedJSObject || window;

function Autocomplete(inputField, box, autocompleteStore, callback)
{
this.inputField = inputField;
this.box = box;
this.autocompleteList = new AutocompleteList(inputField, autocompleteStore, this);
this.callback = callback;
this.hide();
this.bind();
}

Autocomplete.prototype.show = function()
{
this.box.wrappedJSObject.style.display = "block";
this.inputField && this.inputField.focus();
}

Autocomplete.prototype.hide = function()
{
this.box.wrappedJSObject.style.display = "none";
this.inputField && (this.inputField.value = "");
this.autocompleteList.clearOutput();
}

Autocomplete.prototype.doCallback = function()
{
var completion = this.autocompleteList.getCurrentCompletion();
this.hide();
this.callback(completion);
}

Autocomplete.prototype.bind = function()
{
var autocompleteList = this.autocompleteList;
var inputField = this.inputField;
var currentText = "";

var handleKeyPressEvent = function(event)
{
currentText = inputField.value;
if (event.keyCode == 9) // Tab
{
if (window.wrappedJSObject.utility)
window.wrappedJSObject.utility.stopEvent(event);
return false
}
else if (autocompleteList.isVisible)
{
if (event.keyCode == 13)// Enter
autocompleteList.parent.doCallback();
if (event.keyCode == 40)// Key down
autocompleteList.highlightNextCompletion();
else if (event.keyCode == 38) // Key up
autocompleteList.highlightPreviousCompletion();
else if (event.keyCode == 27) // Esc
autocompleteList.clearOutput();
}
else if (event.keyCode == 27)
autocompleteList.parent.hide();

return true;
};
var handleKeyUpEvent = function(event)
{
if (currentText === null || currentText != inputField.value)
autocompleteList.update();
};
var handleClickEvent = function(event)
{
if (autocompleteList.isVisible)
autocompleteList.hideOutput();

if (window.wrappedJSObject.utility)
window.wrappedJSObject.utility.stopEvent(event);
}

this.inputField.setAttribute("autocomplete", "off");
this.inputField.addEventListener("keypress", handleKeyPressEvent, false);
this.inputField.addEventListener("keyup", handleKeyUpEvent, false);
this.box.addEventListener("click", handleClickEvent, false);
this.autocompleteList.createOutput();
}

function AutocompleteList(inputField, autocompleteStore, parent)
{
this.inputField = inputField;
this.autocompleteStore = autocompleteStore;
this.parent = parent;
this.output = null;
this.completions = null;
this.position = -1;
this.isVisible = false;
}

AutocompleteList.prototype.createOutput = function()
{
if (!this.inputField) return;

this.output = document.createElement('div');
this.output.setAttribute('id','autoCompleteList_' + this.inputField.id);
this.output.style.border = "solid 1px black";
this.output.style.background = "white";
this.output.style.position = "absolute";
this.output.style.width = "150px";
this.output.style.visibility = "hidden";

this.inputField.parentNode.insertBefore(this.output, this.inputField.nextSibling);
}

AutocompleteList.prototype.showOutput = function()
{
this.output && (this.output.style.visibility = "visible");
this.isVisible = true;
}

AutocompleteList.prototype.hideOutput = function()
{
this.output && (this.output.style.visibility = "hidden");
this.isVisible = false;
}

AutocompleteList.prototype.clearOutput = function()
{
while(this.output && this.output.childNodes.length)
this.output.removeChild(this.output.firstChild);

this.position = -1;
this.hideOutput();
}

AutocompleteList.prototype.addCompletion = function(completion)
{
var autocompleteList = this;

var mouseOverHandler = function(event)
{
autocompleteList.position = this.position;
autocompleteList.highlightCompletion();
}

var mouseClickHandler = function(event)
{
autocompleteList.parent.doCallback();
}

var completionBox = document.createElement("div");
completionBox.style.textAlign = "left";
completionBox.style.paddingLeft = "2px";
completionBox.appendChild(document.createTextNode(completion));
completionBox.wrappedJSObject.position = this.output.childNodes.length;
completionBox.addEventListener("mouseover", mouseOverHandler, false);
completionBox.addEventListener("click", mouseClickHandler, false);
this.output.appendChild(completionBox);
}

AutocompleteList.prototype.highlightCompletion = function()
{
if (this.output && this.output.childNodes)
{
for (var i = 0; i < this.output.childNodes.length; ++i)
{
if (i == this.position)
{
this.output.childNodes[i].style.color = "white";
this.output.childNodes[i].style.background = "#316ac5";
}
else
{
this.output.childNodes[i].style.color = "black";
this.output.childNodes[i].style.background = "white";
}
}
}
}

AutocompleteList.prototype.highlightNextCompletion = function()
{
if (this.completions && this.completions.length > 0 && this.position < this.completions.length - 1)
{
++this.position;
this.highlightCompletion();
}
}

AutocompleteList.prototype.highlightPreviousCompletion = function()
{
if (this.completions && this.completions.length > 1 && this.position > 0)
{
--this.position;
this.highlightCompletion();
}
}

AutocompleteList.prototype.getCurrentCompletion = function()
{
if (this.completions && this.completions.length > 0)
return this.completions[this.position];

return null;
}

AutocompleteList.prototype.update = function()
{
if (this.inputField.value.length > 0)
{
this.completions = this.autocompleteStore.getCompletions(this.inputField.value);
if (this.completions && this.completions.length > 0)
{
this.clearOutput();
for (var i = 0; i < this.completions.length; ++i)
this.addCompletion(this.completions[i]);

this.showOutput();
this.highlightNextCompletion();
}
else
{
this.hideOutput();
this.position = -1;
}
}
else
{
this.hideOutput();
this.position = -1;
}
}

function ListAutocompleteStore()
{

}

ListAutocompleteStore.prototype.getCompletions = function(text)
{
if (window.wrappedJSObject.listTabs && window.wrappedJSObject.listTabs.entries && window.wrappedJSObject.listTabs.entries.length > 0)
{
var completions = new Array();

for (var i = 0; i < window.wrappedJSObject.listTabs.entries.length; ++i)
{
if (window.wrappedJSObject.listTabs.entries[i].toLowerCase().indexOf(text.toLowerCase()) == 0)
completions.push(window.wrappedJSObject.listTabs.entries[i]);
}

return completions;
}

return null;
}

window.wrappedJSObject.autocompletes = {};

var createAutoComplete = function(name, callback)
{
var autocompleteBox = document.createElement('div');

autocompleteBox.setAttribute("id", "autocompleteBox_" + name);
autocompleteBox.style.width = "240px";
autocompleteBox.style.position = "absolute";

autocompleteBox.innerHTML = '<div class="white_rbroundbox"> <div class="white_rbtop"> <div> <div></div> </div> </div> <div class="white_rbcontentwrap"> <div class="white_rbcontent"> <div class="taskcloudcontent" style="padding: 0px 5px 0px 5px; height: 17px;" id="listtabscontainer"><div style="width: 70px; font-weight: bold; float: left; height: 17px; padding-top: 1px;">' + name + '</div><div style="text-align: right; float: right; width: 155px; padding-right: 2px;"><input type="text" id="autocompleteInputField_' + name + '" name="text" style="width: 151px; ";/></div> </div> </div> </div> <div class="white_rbbot"> <div><div></div> </div> </div> </div> ';

document.body.appendChild(autocompleteBox);
var autocomplete = new Autocomplete(document.getElementById("autocompleteInputField_" + name),
document.getElementById("autocompleteBox_" + name),
new ListAutocompleteStore(),
callback);

function centerAutoCompleteBox()
{
var left = window.wrappedJSObject.innerWidth / 2 - 120 + window.wrappedJSObject.scrollX;
var top = window.wrappedJSObject.innerHeight / 2 - 10 + window.wrappedJSObject.scrollY;

autocompleteBox.style.left = left + "px";
autocompleteBox.style.top = top + "px";
}

centerAutoCompleteBox();
window.addEventListener("scroll", centerAutoCompleteBox, false);
window.addEventListener("resize", centerAutoCompleteBox, false);

return autocomplete;
}

var createAutoCompletes = function()
{
window.wrappedJSObject.autocompletes["goTo"] = createAutoComplete("GO TO: ", selectListByName);
window.wrappedJSObject.autocompletes["moveTo"] = createAutoComplete("MOVE TO: ", moveToListByName);
}

var moveToListByName = function(text)
{
if (!window.wrappedJSObject.listTabs || !window.wrappedJSObject.listTabs.entries)
return;

for (var i = 0; i < window.wrappedJSObject.listTabs.entries.length; ++i)
{
if (window.wrappedJSObject.listTabs.entries[i].toLowerCase() == text.toLowerCase())
window.wrappedJSObject.control.tasksSelectionChanged("", ["", "tasks.moveTo." + window.wrappedJSObject.listTabs.data[i][1]]);
}
}

var selectListByName = function(text)
{
if (!window.wrappedJSObject.listTabs || !window.wrappedJSObject.listTabs.entries)
return;

for (var i = 0; i < window.wrappedJSObject.listTabs.entries.length; ++i)
{
if (window.wrappedJSObject.listTabs.entries[i].toLowerCase() == text.toLowerCase())
window.wrappedJSObject.listTabs.selectTabByPosition(i);
}
}

var hideAutocompletes = function()
{
if (window.wrappedJSObject.autocompletes)
for (var name in window.wrappedJSObject.autocompletes)
window.wrappedJSObject.autocompletes[name].hide();
}

// end Autocomplete

var createLeftColumn = function()
{
var leftColumn = document.createElement('div');
var appView = document.getElementById("appview");
var listBox = document.getElementById("listbox");

leftColumn.setAttribute('id','leftColumn');
leftColumn.style.cssFloat = "left";
leftColumn.style.paddingLeft = "5px";
leftColumn.style.paddingRight = "8px";
leftColumn.style.display = "none";

if (appView && listBox)
appView.insertBefore(leftColumn, listBox);
}

var createListTabsContainer = function()
{
var listTabsBox = document.createElement('div');
var leftColumn = document.getElementById("leftColumn");

if (leftColumn)
{
listTabsBox.innerHTML = '<div class="white_rbroundbox"> <div class="white_rbtop"> <div> <div></div> </div> </div> <div class="white_rbcontentwrap"> <div class="white_rbcontent"> <table><tr><td><div class="taskcloudcontent" style="padding: 0px 5px 0px 5px;" id="listtabscontainer"> </div></td></tr></table> </div> </div> <div class="white_rbbot"> <div><div></div> </div> </div> </div> ';

leftColumn.appendChild(listTabsBox);
}
}

var moveListTabs = function()
{
var listTabs = document.getElementById("listtabs");
if (listTabs)
{
listTabs.className = "";
listTabs.style.width = "100%";

var listTabsContainer = document.getElementById("listtabscontainer");

if (listTabsContainer)
listTabsContainer.appendChild(listTabs);
}
}

var hideLeftColumn = function()
{
var content = document.getElementById("content");
var leftColumn = document.getElementById("leftColumn");

if (leftColumn)
{
leftColumn.style.display = "none";
content.style.width = "980px";
}
}

var showLeftColumn = function()
{
var content = document.getElementById("content");
var leftColumn = document.getElementById("leftColumn");
var listTabsContainer = document.getElementById("listtabscontainer");

if (leftColumn)
{
leftColumn.style.display = "block";
leftColumn.style.width = Math.round(listTabsContainer.clientWidth * 1.14) + "px";
content.style.width = (973 + leftColumn.clientWidth) + "px";
}
}

var moveTabsToTheLeft = function()
{
var content = document.getElementById("content");
var listBox = document.getElementById("listbox");
var tools_spacer = document.getElementById("tools_spacer");
var sorting = document.getElementById("sorting");
var tools = document.getElementById("tools");

createLeftColumn();
createListTabsContainer();
moveListTabs();

var leftColumn = document.getElementById("leftColumn");

var handleViewChanged = function(d, e)
{
if (e[0][1] == "Tasks")
hideLeftColumn();
else if (e[1][1] == "Tasks")
showLeftColumn();
}

if (window.wrappedJSObject.messageBus)
window.wrappedJSObject.messageBus.subscribe(handleViewChanged, window.wrappedJSObject.view.getUniqueMessageBusName() + "viewChanged");

if (tools_spacer)
{
tools_spacer.style.paddingTop = "1px";
tools_spacer.style.borderTop = "1px solid #CACACA";
}

if (sorting)
sorting.style.marginTop = "0px";

if (tools)
tools.style.paddingTop = "5px";

if (content && window.wrappedJSObject.view)
{
if (window.wrappedJSObject.view.getSelected() == "Tasks")
showLeftColumn();
else
hideLeftColumn();
}
}

var handleKeyPressEvent = function(ev, ignoreCombo)
{
ev || (ev = window.event);

if (ev == null)
return;

var target = null;

if (window.wrappedJSObject.utility)
target = window.wrappedJSObject.utility.getEventTarget(ev);

if (target == null)
return true

var pressed = (ev.charCode) ? ev.charCode: ((ev.which) ? ev.which: ev.keyCode);

if (target != null && target.type != null && (target.type == "textarea" || target.type == "input" || target.type.indexOf("select") == 0 || target.type == "button" || target.type === "submit" || target.type == "text" || target.type == "password" || (target.id != null && target.id == "map")))
return true

var tabs = null;

if (window.wrappedJSObject.view)
tabs = window.wrappedJSObject.view.getViewTabs();

if (tabs)
{
switch (pressed)
{
case 74:
if (ev.shiftKey)
{
tabs.selectRight();
if (window.wrappedJSObject.utility)
window.wrappedJSObject.utility.stopEvent(ev);

return false
}
break;
case 75:
if (ev.shiftKey)
{
tabs.selectLeft();
if (window.wrappedJSObject.utility)
window.wrappedJSObject.utility.stopEvent(ev);

return false
}
break;
case 103:
if (ev.ctrlKey)
{
hideAutocompletes();
window.wrappedJSObject.autocompletes["goTo"] && window.wrappedJSObject.autocompletes["goTo"].show();
if (window.wrappedJSObject.utility)
window.wrappedJSObject.utility.stopEvent(ev);

return false;
}
break;
case 109:
if (ev.ctrlKey)
{
hideAutocompletes();
window.wrappedJSObject.autocompletes["moveTo"] && window.wrappedJSObject.autocompletes["moveTo"].show();
if (window.wrappedJSObject.utility)
window.wrappedJSObject.utility.stopEvent(ev);

return false;
}
break
}
}

return true;
}

var overrideBodyKeyPressHandler = function()
{
if (window.wrappedJSObject.eventMgr)
{
var oldBodyKeyPressHandler = window.wrappedJSObject.eventMgr.bodyKeyPressHandler;

window.wrappedJSObject.eventMgr.bodyKeyPressHandler = function(ev, ignoreCombo)
{
if (handleKeyPressEvent(ev, ignoreCombo))
return oldBodyKeyPressHandler.call(window.wrappedJSObject.eventMgr, ev, ignoreCombo);

return true;
}
}
}

var overrideListTabsBlitDiv = function()
{
if (window.wrappedJSObject.listTabs)
{
var oldBlitDiv = window.wrappedJSObject.listTabs.blitDiv;

window.wrappedJSObject.listTabs.blitDiv = function()
{
oldBlitDiv.call(window.wrappedJSObject.listTabs);
refreshListTabsStyles();
showTasksCount();
hideLists();
}

window.wrappedJSObject.listTabs.blitDiv();
}
}

var refreshListTabsStyles = function()
{
var divListTabs = document.getElementById("listtabs");

if (divListTabs)
{
divListTabs.firstChild.style.listStyle = "none";
divListTabs.firstChild.style.padding = "0px 5px 0px 5px";
divListTabs.firstChild.style.whiteSpace = "nowrap";
}
}

var hideLists = function()
{
if (window.wrappedJSObject.listTabs)
{
var listItems = window.wrappedJSObject.listTabs.div.getElementsByTagName("li");

for (var i = 0; i < window.wrappedJSObject.listTabs.data.length; ++i)
{
if (window.wrappedJSObject.listTabs.data[i] && isListHidden(window.wrappedJSObject.listTabs.data[i][1]))
listItems[i].style.display = "none";
}

/*if (window.wrappedJSObject.view.getSelected() == "Tasks")
showLeftColumn();*/
}
}

var overrideListTabsSelectLeft = function()
{
if (window.wrappedJSObject.listTabs)
{
var oldListTabsSelectLeft = window.wrappedJSObject.listTabs.selectLeft;

window.wrappedJSObject.listTabs.selectLeft = function()
{
var position = this.selected - 1;

while (true)
{
if (position >= 0)
{
if (!isListHidden(this.data[position][1]))
break;

--position;
}
else
position = this.entries.length - 1;
}

this.selectTabByPosition(position);
}
}
}

var overrideListTabsSelectRight = function()
{
if (window.wrappedJSObject.listTabs)
{
var oldListTabsSelectRight = window.wrappedJSObject.listTabs.selectRight;

window.wrappedJSObject.listTabs.selectRight = function()
{
var position = this.selected + 1;

while (true)
{
if (position < this.entries.length)
{
if (!isListHidden(this.data[position][1]))
break;

++position;
}
else
position = 0;
}

this.selectTabByPosition(position);
}
}
}

var showTasksCount = function()
{
if (window.wrappedJSObject.listTabs)
{
var listItems = window.wrappedJSObject.listTabs.div.getElementsByTagName("li");

for (var i = 0; window.wrappedJSObject.listTabs.data && window.wrappedJSObject.listTabs.data[i]; ++i)
{
var tasksCount = 0;

if (window.wrappedJSObject.listTabs.data[i][2])
{
var filter = window.wrappedJSObject.listTabs.data[i][2];

if (filter && filter.indexOf("status:") < 0)
filter = "(" + filter + ") and (status:incomplete)";

if (window.wrappedJSObject.overviewList && filter)
tasksCount = window.wrappedJSObject.overviewList.getFilteredList(filter).length
}
else
{
if (window.wrappedJSObject.format)
tasksCount = window.wrappedJSObject.format.getListStatistics(window.wrappedJSObject.listTabs.data[i][1])[5];

listItems[i].firstChild.style.color = "black";
}

if (tasksCount > 0)
listItems[i].firstChild.innerHTML = listItems[i].firstChild.innerHTML + " (" + tasksCount + ")";
}
}
}

var subscribeToFilterEditFinished = function()
{
if (window.wrappedJSObject.messageBus)
window.wrappedJSObject.messageBus.subscribe(window.wrappedJSObject.listTabs.blitDiv, window.wrappedJSObject.listList.mbn + "setFilterSuccess");
}

var overrideTaskCloudUpdate = function()
{
if (window.wrappedJSObject.taskCloud)
{
var oldTaskCloudUpdate = window.wrappedJSObject.taskCloud.update;

window.wrappedJSObject.taskCloud.update = function()
{
oldTaskCloudUpdate.call(window.wrappedJSObject.taskCloud);

if (window.wrappedJSObject.listTabs)
window.wrappedJSObject.listTabs.blitDiv();
}
}
}

//var hiddenLists = GM_getValue("hiddenLists", "");
var hiddenLists = "";

var isListHidden = function(listID)
{
if (hiddenLists)
return hiddenLists.indexOf(listID) >= 0;

return false;
}

var isListArchived = function(listID)
{
if (window.wrappedJSObject.stateMgr.lists[listID] && window.wrappedJSObject.stateMgr.lists[listID].archived)
return true;

return false;
}

var hideList = function(entry)
{
hiddenLists = (hiddenLists || "") + entry[0] + ",";

GM_setValue("hiddenLists", hiddenLists);

window.wrappedJSObject.listList.list.updateEntry(entry);
window.wrappedJSObject.listTabs.blitDiv();
}

var showList = function(entry)
{
hiddenLists = hiddenLists.replace(entry[0], "");
hiddenLists = hiddenLists.replace(",,", ",");

GM_setValue("hiddenLists", hiddenLists);

window.wrappedJSObject.listList.list.updateEntry(entry);
window.wrappedJSObject.listTabs.blitDiv();
}


var overrideListListUpdateEntry = function()
{
if (window.wrappedJSObject.listList)
{
var oldListListUpdateEntry = window.wrappedJSObject.listList.list.updateEntry;

window.wrappedJSObject.listList.list.updateEntry = function(entry, D)
{
oldListListUpdateEntry.call(window.wrappedJSObject.listList.list, entry, D);

var index = window.wrappedJSObject.listList.list.map[entry[0]];
var row = window.wrappedJSObject.listList.list.table.rows[index];

row.entry = entry;
row.rowText.innerHTML = "<div id='listName_" + entry[0] + "' style='float: left;'>" + entry[1] + "</div><div style='align: right; float: right;'><a href=\"# \" id='displayListLink_" + entry[0] + "'></a></div>";

var displayListLink = document.getElementById('displayListLink_' + entry[0]);
var listName = document.getElementById('listName_' + entry[0]);

var listClickHandler = function(event)
{
if (isListHidden(entry[0]))
showList(entry);
else
hideList(entry);


if (window.wrappedJSObject.utility)
window.wrappedJSObject.utility.stopEvent(event);
}

displayListLink.addEventListener('click', listClickHandler, false);

if (!isListArchived(entry[0]))
{
if (isListHidden(entry[0]))
{
displayListLink.innerHTML = "show";
listName.style.color = "#cacaca";
}
else
{
displayListLink.innerHTML = "hide";
listName.style.color = "";
}
}
}

window.wrappedJSObject.listList.doStyles();
}
}

window.addEventListener('load', overrideListTabsBlitDiv, false);
window.addEventListener('load', moveTabsToTheLeft, false);
window.addEventListener('load', overrideBodyKeyPressHandler, false);
window.addEventListener('load', overrideTaskCloudUpdate, false);
window.addEventListener('load', overrideListTabsSelectLeft, false);
window.addEventListener('load', overrideListTabsSelectRight, false);
window.addEventListener('load', subscribeToFilterEditFinished, false);
window.addEventListener('load', createAutoCompletes, false);
window.addEventListener('click', hideAutocompletes, false);

window.addEventListener('load', overrideListListUpdateEntry, false);

2009年2月6日金曜日

バンテリン

このエントリーをはてなブックマークに追加
僕は腰痛持ちなので、バンテリンが手放せません。
最初はさほど効果が無いと思っていたのですが、とある人から
「1時間位風呂に浸かった後、バンテリン塗ると効果三倍」
って言われたので試して見たらめっちゃ効く!
バンテリン侮りがたしっ!

なので、本当に手放せないです。
今日も軽い腰痛だったので、長風呂の後バンテリンを塗付しました。
って事で今はぅうううう状態になっています。
あの沁みる感じが何とも言えないです。


変態じゃないよ! 腰痛持ちという名の紳士だよ!
#紳士って腰痛持ちなのかなぁ

2009年2月5日木曜日

ニコニコ動画の広告を消すだけなら

このエントリーをはてなブックマークに追加
UserScriptではなく、UserCSSで対応できるよねって話。
元ネタはこちら

で、対応するCSSはこれ。
もう少しシンプルに書けるかもしれないけどまあ良いや。

div#PAGEHEADER table tbody tr td table + table { float: right !important; margin-top:-40px !important;}
div#PAGEHEADER table tbody tr td div{ display:none !important; }

二行目のCSSで広告と「前回の検索結果、閲覧したマイリストを記録できます【行動履歴をON】」ってリンクを消している。
なので、このリンクが欲しければこのCSSは使う価値無し(ぇー
別に要らないけどね、自分としては。

FirefoxならStylish一発だよねー

@namespace url(http://www.w3.org/1999/xhtml);

@-moz-document domain("www.nicovideo.jp") {
div#PAGEHEADER table tbody tr td table + table { float: right !important; margin-top:-40px !important;}
div#PAGEHEADER table tbody tr td div{ display:none !important; }
}


2:46追記
CSS好きな人から一行目の添削貰ったので、それにチェンジ

2009年2月4日水曜日

memo

このエントリーをはてなブックマークに追加

ただし、「CheckInstall」のヴァージョン1.6.1にはバグがあり、
エラー: アーカイブの伸長に失敗: ファイル /bin/sed;47779bda: cpio: MD5 チェックサムが適合しません。
というメッセージが表示される為、--nomd5オプションを付加してインストールする。
rpm -ivh --nomd5 /usr/src/redhat/RPMS/i386/checkinstall-1.6.1-1.i386.rpm <= 「CheckInstall」のインストール


引用元http://www.crimson-snow.net/tips/linux/checkinstall.html

これは愚痴です

このエントリーをはてなブックマークに追加
/*愚痴ここから

OpenID使った認証のCGI作ってるんだけどまともに動かない。
セッション関係のところがうまく行ってない。
認証して、セッション保存してるはずなのに、保存されていないという謎現象が起きている。
なんぞこれー。
認証は多分問題なくて、セッション保存に問題あると見た。
今日は解決しなかったので、また明日続きをやろう。

愚痴ここまで*/