Home > 技術

技術 Archive

Vimをちゃんと使い始めてみる

僕が大好きなTextMateのカラーテーマMonokai » Blog Archive » Textmate color themeVim版があったので、もうこうなったらちゃんとやる!
Vimをちゃんとやる!
ということで、とりあえずやった設定と.vimrc.gvimrcをメモしておく。

Vimはちょいちょい使ってみてはいるんですが、すぐにTextMateやWebStormなんかに浮気して、すぐに使わなくなって、また使う頃にはコマンドほとんど覚えていない現象に陥っているので、今後は小さなtxtファイルの編集でもなるべくVimを使って行ってみようと思う。
とはいえ、コーディングはTextMateになるんだとは思いますが...

vimのカラースキーマを変更する

僕はいっつもエディターをいじるときに色から入ります。
色がうまいこといかないと、ヘコみます。

XXX.vimファイルをダウンロードし、以下のディレクトリに配置する。

カラースキーマの保存場所 - windowsの場合

$HOME/vimfiles/colors/

カラースキーマの保存場所 - macの場合

$HOME/.vim/colors/

colorschemeを選ぶ

新卒さんのための人気Vimカラースキーマランキング5+1(vim.org & github調べ) - 常識という迷信
を参考に、molokai - A port of the monokai scheme for TextMate : vim onlineにしてみました。

これはTextMateのほうで僕はこの色を使っているので、もうこれ以外考えられないです!
Monokai » Blog Archive » Textmate color theme

■参考リンク
カラースキーマの使い方 -- 名無しのvim使い

.gvimrcにcolorschemeの設定を書く

MacVim-KaoriYaでcolorschemeの設定 - 脳みそHack
これ毎回ハマるんですが、MacVim-KaoriYaの設定ファイルの読み込みの順番が

MacVim.app/Contents/Resources/vim/vimrc


ホームフォルダ/.vimrc または _vimrc


MacVim.app/Contents/Resources/vim/gvimrc


ホームフォルダ/.gvimrc または _gvimrc


via: MacVim-KaoriYaでcolorschemeの設定 - 脳みそHack

なので、.vimrcに書いてもいまいちcolorschemeが反映されない。
なので、.gvimrcをtouchにしてここに、

colorscheme molokai

と記載します。
これでテーマがちゃんと反映されます。

またカラースキーマ -- 名無しのvim使いにたくさんテーマがあるので、自分に合うのを探してみるのも楽しいかもしれません。

タブと全角スペースは色を変える

はじめ.vimrcのほうにいろいろと書いてためしてみたんですが、いっこうに全角スペースが可視化されなくてハマってて、
どうやら.gvimrcに書くのがいいみたい。

Vim初心者的導入メモ 2/3 「vimrc設定」編 - ナレッジエース
から

"全角スペースを視覚化
highlight ZenkakuSpace cterm=underline ctermfg=lightblue guibg=#666666
au BufNewFile,BufRead * match ZenkakuSpace / /

を拝借。

タブの表示に関しては、vimでスペースやTabなどの見えない文字を表示させる方法 - Life is Try and Errorを参考にさせていただいた。

"特殊文字(SpecialKey)の見える化。listcharsはlcsでも設定可能。
"trailは行末スペース。
set list
set listchars=tab:>-,trail:-,nbsp:%,extends:>,precedes:<

上記2つを.gvimrcに追記すればOK!


Pluginを入れる

Zen-Coding

やっぱりZenがないと不便!

ZenCoding for Vim 導入方法(初心者さん向け) - sakurako_sの日記

vimのプロセス間でのコピペ

複数のvimプロセス間でコピペするためのplugin - while(1){die; respawn;}

vimからTextMateへもペーストできるので便利!

vim-autocomplpop

autocomplpop.vimを入れてやったこと-vimプラグイン - rderaログを見ながら入れてみた。
入力補完プラグイン。

C-pとかC-nで移動して、C-yで選択がデフォルトみたいだけど。


やはり、tabで移動したい。


via: autocomplpop.vimを入れてやったこと-vimプラグイン - rderaログ

のタブ切り替えは非常に便利。


便利機能

括弧とかダブルコート入力時に←に戻る

「もっと早く知りたかった」と思ったvimrc設定 - e2esound.com業務日誌

この設定のおかげで今後のvimライフが大きく左右されるんだろうなー。

を.vimrcに追記すればOK!

Esc以外でノーマルモードに戻る方法

Vimにおける Esc と Ctrl-cの違い。 - 備忘録 betaの記事を読むと、

  • Ctrl + c
  • Ctrl + [

とこの2つの方法があるようですが、Ctrl + cのほうは、ちょっとクセがありそうなので、Ctrl + [が今後活躍しそうです。
でも、Escはちょっと遠いけど、慣れるとEscが一番速そう。


.vimrc

.gvimrc

hisasann/vimrc - GitHub

さぁて、Vimライフをおくりはじめますか!

追伸:WindowsではPeggyというエディターをよく使っております!

■関連リンク
vimに欠かせない3つのプラグイン | tech.kayac.com - KAYAC engineers' blog
Vim初心者的導入メモ 2/3 「vimrc設定」編 - ナレッジエース
vimrcを晒してみる - Archiva
ぼちぼち散歩 おれの.vimrc

Vimテクニックバイブル ~作業効率をカイゼンする150の技
Vimサポーターズ
技術評論社
売り上げランキング: 43182

さくらVPSでnginxをインストールしたときのメモ

極々メモ的な感じで、エントリーにしとく。

apacheのリバースプロキシ用にmod_rpafのインストール

のちのち必要になるのでまずはmod_rpafのインストールから。

wget http://stderr.net/apache/rpaf/download/mod_rpaf-0.6.tar.gz
tar xvzf mod_rpaf-0.6.tar.gz
cd mod_rpaf-0.6

Makefileをちょっと書き換える。

vi Makefile

-APXS2=$(shell which apxs)
+APXS2=/usr/sbin/apxs

makeしてみる。

make rpaf-2.0
sudo make install-2.0

apxsがないとエラーが出たので、httpd-develをインストール

httpd-develのインストール

sudo yum install httpd-devel

今度はhttpd-develを探しにいけなかったようなので、rpmを追加。

Loaded plugins: fastestmirror
Loading mirror speeds from cached hostfile
* base: ftp.nara.wide.ad.jp
* extras: ftp.nara.wide.ad.jp
* updates: ftp.nara.wide.ad.jp
Setting up Install Process
No package http-devel available.
Nothing to do
となったのでリポジトリを追加する

適当なディレクトリでwgetしてrpmファイルをダウンロードしとく。
そしてrpmコマンドで登録します。

wget http://download.fedora.redhat.com/pub/epel/5/x86_64/epel-release-5-4.noarch.rpm
wget http://rpms.famillecollet.com/el5.x86_64/remi-release-5-8.el5.remi.noarch.rpm
wget http://packages.sw.be/rpmforge-release/rpmforge-release-0.5.2-2.el5.rf.x86_64.rpm

rpm -Uvh epel-release-5-4.noarch.rpm remi-release-5-8.el5.remi.noarch.rpm rpmforge-release-0.5.2-2.el5.rf.x86_64.rpm

これで再度、

sudo yum install httpd-devel

実行したらうまく入った!

nginxのインストール

sudo yum install nginx

一応入ったことを確認しとく。

yum list installed | grep nginx

設定ファイルnginx.confの編集

nginx+apacheでちょっぴり快適なWebサーバーを目指してみる(CentOS さくらのVPS) ::ハブろぐからごっそり参考にさせていただいた!

バーチャルホストvirtual.confの編集

apacheのhttpd.confの編集

リバースプロキシを導入する際はmod_rpaf :: drk7jp
mod_rpafを使ったIPアドレスのアクセス制限

apacheとnginxの再起動

sudo /etc/init.d/httpd restart
sudo /etc/init.d/nginx restart

こんなこともあるみたい。

nginxを再起動させます。


注意:このとき、sudo /etc/init.d/nginx restartを使わないこと。再起動しないことがよくありました。


sudo /etc/init.d/nginx stop
sudo /etc/init.d/nginx start


via: nginx @ ウィキ - nginx バーチャルホスト

実際にアクセスしてみる

アクセスしてみると、

/var/www/htmlに置いたhtmlはちゃんと表示されるのに、
自分で作成した/home/hisasann/www/test2に置いたファイルを開こうとしても、

(13)Permission denied: access to /index.html

となってしまった。

原因は、途中のディレクトリのhisasannが700だったから!
apache を利用しての public_html が公開できない - 解 - いろきゅう.jp ~Programmable maiden~ Tech side
[Linux]ApacheがPermission deniedを吐いてくる : うえちょこ@ぼろぐ
(結構これにハマッテいる人がいて、SELinuxというものが悪さしている場合もあるよう)

これで
静的ファイル
「http://www28039u.sakura.ne.jp/sample.jpg」
/home/hisasann/www/test/にアクセスされ、
動的ファイル
「http://www28039u.sakura.ne.jp/test2.html」
/home/hisasann/www/test2/にアクセスされるようになった。

まだ分からないことだらけですが、なかなか面白い!

■参考リンク
さくら VPS + CentOS のチューニングや高速化もっとこうすれば良かった作業まとめ | ウェブル
さくら VPS で 静的ファイルは nginx で動的ファイルは Apache で処理するための詳細設定 | ウェブル
nginx+apacheでちょっぴり快適なWebサーバーを目指してみる(CentOS さくらのVPS) ::ハブろぐ
軽量高速Webサーバのnginxで静的コンテンツ配信とキャッシュコントロール | KRAY Inc

ハイパフォーマンスHTTPサーバ Nginx入門
Clement Nedelcu
アスキー・メディアワークス
売り上げランキング: 14072

iDance - Thank you Steve.

gamen.png

webkitAudioContextを使って音とcanvasへの描画をシンクロさせてみました。
あまり情報が多くなく、試行錯誤でしたがなんとかそれっぽくなったと思います。

canvasへの描画は、Paper.jsを使いました。
これぐらいならライブラリを使う必要なかったのですが、Paper.jsが気になっていたのでとりあえず慣れるということで。

また、今回のこのアプローチはken_c_loさんからアイデアをいただきました。
画像の提供から配置までのデザインを担当してもらい、ありがとうございます!

この作品をスティーブ・ジョブズ氏に捧げます。

iDance - Thank you Steve.

Chromeでご覧ください。(音が出ます)
iDance - Thank you Steve.

■github
hisasann/iDance - GitHub

AudioDance

こちらはiDanceの元となった作品です。
スピーカー画像を使って表現してみました。是非こちらもご覧ください。
AudioDance

■github
hisasann/AudioDance - GitHub

Steve Jobs
Steve Jobs
posted with amazlet at 12.01.27
Walter Isaacson
Simon & Schuster (2011-10-24)
売り上げランキング: 3

さくらVPSにApacheをインストールする方法

パッケージからインストールする

楽チン!

[root]$ yum -y install httpd
[root]$ /etc/rc.d/init.d/httpd start
Starting httpd: [ OK ]

自動起動にする

[root]$ chkconfig httpd on
[root]$ chkconfig --list httpd
httpd 0:off 1:off 2:on 3:on 4:on 5:on 6:off

3がonになっていればよい。

[root]$ chkconfig --list

これで自動起動の設定を確認できる

Apacheのバージョンを確認する

[root]$ rpm -qa httpd

あとはhttpでアクセスしてApacheの画面が表示されてばOK!

[via]
26.3. chkconfigコマンドによる自動起動の設定

さくらVPSを使うときの初期設定メモ

むちゃくちゃザックリとして内容ですが、自分のために一応メモしとく。

何はともあれ接続する

パスワードはさくらインターネットから送られてくるメールに記載されている初期パスワードを入力する。

[makbook]$ ssh root@IPアドレス

真っ先にrootのパスワード変更する

[root]$ passwd
Changing password for user root.
New UNIX password:
Retype new UNIX password:
passwd: all authentication tokens updated successfully.

続いて今後メインに使っていくことになるユーザーを作成する

[root]$ useradd username[Enter]
[root]$ passwd username[Enter]
Changing password for user username.
New UNIX password:[新しいパスワードを入力]
Retype new UNIX password:[新しいパスワードを再入力]
passwd: all authentication tokens updated successfully.

[root]$ usermod -G wheel username

MacBookでSSH接続用のRSA鍵を作成する

[makbook]$ ssh-keygen [Enter]
Generating public/private rsa key pair.
Enter file in which to save the key (/Users/username/.ssh/id_rsa): [Enter]
Enter passphrase (empty for no passphrase): [好きなパスワードを入力]
Enter same passphrase again: [好きなパスワードを再入力]
Your identification has been saved in /Users/username/.ssh/id_rsa.
Your public key has been saved in /Users/username/.ssh/id_rsa.pub.

作成したRSA鍵をサーバーにSCPでコピーする

[macbook]$ cd .ssh
[macbook .ssh]$ scp id_rsa.pub [username]@[IPアドレス]:~/

[username]$ mkdir .ssh
[username]$ chmod 700 .ssh
[username]$ cat id_rsa.pub >> authorized_keys
[username]$ mv authorized_keys .ssh/
[username]$ cd .ssh
[username .ssh]$ chmod 600 authorized_keys

MacBookからSSH接続の確認をする

ターミナルから、以下を入力する。

ssh username@IPアドレス

初回はRSA鍵を作成した時のパスワード入力を促されるけど、2回目からは聞かれない。

sudo設定の変更

作業用ユーザで sudo ができるよう設定を変更します。

[root]$ visudo
%wheel ALL=(ALL) ALL //コメントアウトを外す

サーバーのSSH設定の変更

[root]$ vi /etc/ssh/sshd_config

PermitRootLogin no # rootログイン禁止(一応明示的に)
PasswordAuthentication no # パスワードでログイン禁止(公開鍵暗号オンリー)

[root]$ /etc/init.d/sshd restart

sudoのログを取る

[root]$ touch /var/log/sudo
[root]$ chmod 600 /var/log/sudo

[root]$ visudo
### 末尾に以下を追記
Defaults syslog=local1

[root]$ vi /etc/syslog.conf
local1.* /var/log/sudo # 追加
local7.* /var/log/boot.log

#*.info;mail.none;authpriv.none;cron.none /var/log/messages # コメントアウト
*.info;mail.none;authpriv.none;cron.none;local1.none /var/log/messages # 追加

[root]$ /etc/init.d/syslog restart

[root]$ tail /var/log/sudo
Apr 17 04:55:55 www28039u sudo: username : TTY=pts/0 ; PWD=/home/username ; USER=root ; COMMAND=/bin/su -

SSHポート番号を変更する

[username]$ sudo vi /etc/ssh/sshd_config
#Port 22
Port 10022

[username]$ sudo /etc/init.d/sshd restart
Stopping sshd: [ OK ]
Starting sshd: [ OK ]

[makbook]$ ssh username@IPアドレス -p 10022

文字コードを日本語にする

[root]$ vi /etc/sysconfig/i18n
LANG="ja_JP.UTF-8"

に変更して、ログアウトしてログインする

[via]
さくらのVPS(CentOS)で文字コードを日本語にする方法(もしくはlessで文字化けさせない方法) | IDEA*IDEA

パッケージのアップデートをしとく

Cent OSをインストールした後、「yum update」を行う前に必ず「yum install yum-fastestmirror」すること - Future Insightに書かれているように、

yum install yum-fastestmirror

をやったらすでにインストールされてるって言われた。

[root]$ yum -y update

■参考リンク
さくらのVPS を使いはじめる | アカベコマイリ
さくらVPSにMacでSSH接続する初期設定 @ Eyes of Bastet
「さくらのVPS」借りてみた(作業ユーザー作成,SSH設定) - Rubellum fly light
myfinder's blog: さくらのVPSを借りたら真っ先にやるべきssh設定
【syslog】sudoのログを分ける - nullpopopo
AKIBE - さくらのVPS CentOSでサーバ構築 2 - User

jQueryMobileのXSSに関する調査メモ

今回の原因

#1789: jQuery Mobile XSS Problem by jnlin for jquery/jquery-mobile - Pull Request - GitHubに書かれているXSSが今回の内容。

これは以下のようなhash値をjQueryMobile側のhashchangeイベントがキャッチし、

$()関数にhash値を渡すところで発生するよう。

jQueryMobileの2488行目あたりの以下のコードがそれ。このコードは2360行あたりにも存在する。

そして今回のjQueryのXSSに関する詳しい内容はmalaさんの記事を参考。
jQueryにおけるXSSを引き起こしやすい問題について - 金利0無利息キャッシング - キャッシングできます - subtech
new XSS pattern with jQuery

jQueryMobileのXSSデモUrl

以下のURLを表示するとalertが表示されるのが分かる。

■1.0a4.1
jQuery Mobile: Demos and Documentation

またbeta1のほうでは、

がなくなっており、hash値にimgタグを渡しても発生しない。

■1.0b1
jQuery Mobile: Demos and Documentation

jQueryのバグチケットを見てみる

#9521 (XSS with $(location.hash) and $(#) is needed?) - jQuery Core - Bug Tracker
ここに書いてある解決策である、

はうまくいかなかった。
これはコメント欄を読むと分かるが、「$("anychar<img>")」こうゆうパターンのときにダメのよう。
(何か他にも修正箇所が必要なのだろうか...)

malaさんのパッチを当てる!

ほんとありがたいことですが、こちらのパッチを使ってみたところうまくいきました!
quick patch script for jQuery http://bugs.jquery.com/ticket/9521 -- Gist

こちらのPerlコードは、今回の問題になっているjQuery変数のquickExprの内容を書き換えるものになります。
このパッチには過去古い時代のjQueryのquickExprも含まれているが、とりあえず以下に該当のバージョンのパッチを列挙してみました。

beta1のほうにバージョンアップできる場合は良いのですが、アルファ版とbeta版ではかなり動きや設定も違ってくるので、すぐに対応は難しいと思います。
jQuery MobileにXSSの脆弱性が見つかったのでアルファ版からベータ版に変更する際の注意点[to-R]

とりあえずまだ他のXSSがあるかどうかや今回の件に関する不具合がすべて取り除かれたかの動作確認は出来ておりませんが、
まずはjQuery側を修正し、動作検証をして様子を見てみようと思います。

jquery1.2.6時代のquickExpr用

jquery1.4.2時代のquickExpr用

jquery1.5時代のquickExpr用

いやはや、なかなか難しいもんですなー!

■参考リンク
Twitter / @bulkneets: 冗談みたいな話ですけど旧バージョンのjQuery m ...
Twitter / @bulkneets: jQuery mobileのbeta 1がリリースさ ...
Twitter / @bulkneets: 旧バージョンのjQuery Mobileはじめ多くの ...

jQueryMobileのかゆいところに手が届くお作法メモ

jQueryMobileを使ってのスマートフォンサイトの構築メモの記事ではスマートフォン開発環境の構築に関するTipsとjQueryMobile(以降jqm)のちょっとした書き方に関する内容だったので、今回は「こうゆうときjqmではどうするの?」といったものをサンプルコードを交えてまとめてみようと思います。

サクッとデモだけ見たいーという方はjQueryMobileのかゆいところに手が届くお作法メモからどうぞ。

jqmのページロード時イベントの呼ばれる順番

各イベントに関してはこちらのドキュメントを見ていただくとして、jQuery Mobile Docs - Events

初期ページのロード時の順番

  1. pagebeforecreate
  2. pagecreate
  3. pagebeforeshow
  4. pageshow

Ajaxページ遷移時の順番

遷移元のページをhide系のイベントで見えなくして、遷移先のページをshow系のイベントで見えるようにしています。
その順番は以下のようになりました。

  1. pagebeforecreate
  2. pagecreate
  3. pagebeforehide
  4. pagebeforeshow
  5. pagehide
  6. pageshow

表示される前に何か事前に処理しときたい場合は、pagebeforeshowイベントで処理し、画面が表示された後に何かしたい場合は、pageshowイベントを使うとよいかもしれません。

■デモ
jqmイベントの呼ばれる順番

$.mobile.changePageを独自に呼ぶ(get)

mobileinitイベント内で、$.mobile.ajaxEnabledfalseをセットしています。
これが重要で、この設定をしておけばリンククリック時に勝手にAjaxページ遷移がされないようになります。

あとはクリック時に$.mobile.changePageを呼んであげるだけですが、第4引数をtrueにしときます。
これでhash値が書き換えられるので履歴に残るようになります。

「ajaxEnabledをtrueにした状態でリンクをクリックした場合」と、「changePageを独自に呼ぶ(get)でリンクをクリックした場合」とでは最終的に同じchangePageを呼ぶという意味では違いはほとんどありません。

そしてこのパターンのデメリットとしては、いろんなリンクをクリックしてAjaxページ遷移をしまくるとその分親となるbodyにどんどんHTMLがappendされて肥大していきます。
Ajaxページ遷移するボリュームがそこまででないなら問題はないと思いますが、いろんな条件を見ながら検索条件を絞り込むような画面だとこの遷移が頻繁に起こってしまうのでもしかすると重くなってしまうかもしれません。
(ページが肥大しないようにpostを使った方法を次でご紹介します。)

こちらのデモでは、毎回changePageするたびにカウントアップして別のページを読み込んでいると思わせています。
これで次の画面へ行って戻ってくると画面にはどんどんページが追加されていきます。

■デモ
$.mobile.changePageを独自に呼ぶ(get)

$.mobile.changePageを独自に呼ぶ(post)

こちらのサンプルは$.mobile.changePageを独自に呼ぶ(get)とほとんど同じですが、changePageに渡すtypeがpostになっています。
こうするとhash値はtest.htmlのままで、後ろにhoge=fooが付かないので、パラメータが可変でも常に1つのページを読み込むだけという状態になります。

デモを触っていただくと分かりますが、getのときは画面遷移をするとページ数がどんどん増えていきましたが、postのパターンだと常に2個です。
2個というのは、初期に表示したページと次に読み込んだページの2つという意味です。

パーマリンクとしてhash値にパラメータをちゃんと持たせたいという場合には向きませんが、とくにそういった重要性がない場合はpostを考慮してみるのも一つの方法かもしれません。

■デモ
$.mobile.changePageを独自に呼ぶ(post)

HTML装飾をjqmにさせない

まずはdata-role="page"のタグのdata-themeに適当な文字を入れておきます。
つまりthemeとしては存在しない文字列になります。

これだけだと、コントロール系の要素は勝手に装飾されてしまうので、以下のようにkeepNativeにCSSセレクターを指定しておきます。
以後はこのセレクターをclassに指定した要素は装飾されないようになります。

■デモ
HTML装飾をjqmにさせない

page()でHTMLの装飾

「Ajaxでデータを取得して画面にappendするときにHTMLを装飾したい!」という場合にすごく有力なメソッドがこのpage()です。
以下のサンプルのようにjqmのdata-roleを含んだHTMl文字列をappendして、page()を実行するとまるっと装飾されます。

便利!

■デモ
page()でHTMLの装飾

buttonMarkup()でボタンの装飾

data-rolebuttonを持つ要素を装飾したい場合は、このbuttonMarkup()を使います。
でもぶっちゃけpage()すればいいんだと思います。

■デモ
buttonMarkup()でボタンの装飾

listview()でリストの装飾

ul要素を含むHTMLを装飾したい場合はlistview()を使い、li要素しかない場合はlistview('refresh')を使います。
でもぶっちゃけpage()すればいいんだと思います。

■デモ
listview()でリストの装飾

URLを変えずにAjaxページ遷移+戻る

この需要は意外とあるんじゃないカナーと思うのですが、
たとえば詳細ページから写真の一覧を表示したいけど、hash値を変えるとブラウザバック時に写真一覧に戻っちゃうからヤダッ!
というケース。

Ajaxページ遷移で読み込んだページの戻るボタンは、jqmのものではなく独自の挙動にしたいので$.mobile.page.prototype.options.addBackBtnをfalseにしときます。

遷移元ページの進むと遷移先ページの戻るは同じchangePageを呼び出しますが、
戻るのほうは新たにAjaxページ遷移するのではなくすでに画面にロードされているPageに戻ればよいので第1引数にはid(data-url)を指定します。
さらにトランジションとしては戻るアニメーションをしてほしいので、第3引数はtrueをセットしています。

そして第5引数にtrueをセットして、hash値が変わって呼ばれたということにします。
この引数は確かjQueryMobileのアルファ4からいつの間にか追加されててjQuery Mobile Docs - Methodsにも書かれていません。

遷移元となるページのdata-role="page"のタグにはidを指定しておきます。
このidが戻るときのchangePageのtoになります。

■デモ
URLを変えずにAjaxページ遷移+戻る

hashChangeイベントを自分で監視したい

以下のようにするだけです。

■デモ
hashChangeイベントを自分で監視したい

$.mobile.widgetでカスタムな要素を作る

jqmはチェックボックスやラジオボタンを自動的に装飾してくれますが、そういった処理を自分オリジナルに作ることができます。
以下の例ではHTML要素に対してmarquee()というメソッドを呼ぶとその中にmarqueeタグが挿入されるだけのサンプルになります。

jqmの装飾する処理はDom構築が終わったタイミングで$.mobile.page内から呼ばれる_enhanceControlsメソッドにより行われますが、独自に作ったwidgetは呼ばれないので、readyになったタイミングで呼んであげる必要があります。(当たり前ですね)

そしてmarqueeの値を変更したあとにmarquee("refresh")を呼んでいますが、↑のほうで見たことがある記述ですね。
そう!listview('refresh')と同じですね。

こうゆう感じでwidget化しとくとrefreshするだけで再装飾されるので便利かもしれません。

■デモ
$.mobile.widgetでカスタムな要素を作る

$.mobileの拡張

jqmに特化したコードはjQueryのPluginとして作るとあとあと面倒かもしれないので、$.mobile配下に入れておくとよいかもしれません。

■デモ
$.mobileの拡張

僕のmobileinitイベント

最後に今僕が使っているmobileinitイベントの内容をご紹介。
といってもベタな感じではありますが。

個人的にひとつ重要なのが、$.fixedToolbars.setTouchToggleEnabled(false)です。

これは、headerやらfooterをfixedにした場合に画面内のどこかをタップするとfixedな要素が消えてしまうのを防ぎます。
多分ですが、スマホサイトでよく見るfixedな要素は広告が多く、これが常に追従してくるのはさすがにちょっとという人のためにfixedな要素を消すためにあるのかなーなんて思ってたりします。(違うか!)

広告でしたらサイト訪問者がどこかをタップしてfixedな要素を消すのはよいとは思うのですが、サイトとして重要な要素の場合はタップしようが何しようがfixedでいて欲しいと思うので、このプロパティはfalseにしとくのがよいかと思っています。

まとめ

これらのデモはjQueryMobileのかゆいところに手が届くお作法メモから参照いただけます。

まだまだアルファ版なので仕様がどう変わるか分かりませんが、現時点でのjQueryMobileの完成度としては結構よいのではないかと思っています。
またそもそもデザインも何から何までjQueryMobileに依存するサイト製作は今後あまり浸透せず、イベント回りはjQueryMobile使うけどデザインは独自とかある程度関係性は疎結合として使われていくんじゃないかなーと。

いずれテーマをjQueryMobileのサイト上で作れるようになるとデザインの幅がグッと広がるので楽しみです!

これらのTipsがjQueryMobileを使うの人たち助けになれば幸いです。

■追伸:
vclickイベントって何もんなんだろう・・・

■関連記事
jQueryMobileを使ってのスマートフォンサイトの構築メモ

iPhone+Android スマートフォンサイト制作入門 (WEB PROFESSIONAL)
たにぐちまこと
アスキー・メディアワークス
売り上げランキング: 784

jQueryMobileを使ってのスマートフォンサイトの構築メモ

jQueryMobile2.jpg

徐々にjQuery Mobileのバージョンが上がってきて、だいぶ動きもスピード感もいい感じになってきたので、
そろそろスマートフォンサイトの構築で採用されはじめているのではないでしょうか。
この記事では個人的に、どうやるのか分からなくて調べたことをまとめてみました。

また最新の情報は、jquerymobile (jquerymobile) on Twitterをフォローしとくとよいかもしれません。

では、まずはスマートフォンサイトを構築するときにきっと役に立つTipsからご覧ください。

iPhoneシミュレータ

iPhoney

Macを使っているならiPhoneyがピッタリでしょう。
かなり安定しているし、デザインやJavaScriptの動きもとくに問題ない。

要素の位置やCSSのデザインなどを確認するなら、これがあればよいかも。
最終的には実機で見る必要があるけど、とりあえずこれがあれば困らない。

iPhoney

iBBDemo2

Windows版ならこれが主流なんですかね。
Safariが入っていないと動かないので、まずはSafariのインストールから。

でもSafariで見たときと、iBBDemo2で見たときでデザインの崩れ具合が結構違う。
iBBDemo2はJavaScriptの動きもちょっとおかしいので、実機でも見る前にチョロっと見る用なのかもしれません。

iBBDemo2 - Cross Platform iPad and iPhone Simulator

SafariでUAを変える

Safariの「開発メニュー」 → 「ユーザーエージェント」からiPhone、iPad、iPod Touchなどを選べるのでいずれかを選択。
これだけでスマホなUAになってくれるので、いろんなスマホサイトを見たい場合はこれが一番便利かもしれませんね。
Webインスペクタで要素のチェックなどもできるので便利!。

iPhone SDKに付いてくるiPhone Simulator.appを使う

iOS Dev Center - Apple Developer
より「Xcode and iOS SDK」をインストールするとiPhoneシミュレーターが付いてくるので、これを起動します。

iPhoneプロジェクトを作ってビルドをすると自動で立ち上がるので、それを使ってもいいんですが毎回ビルドするのも面倒なので、
以下の場所にあるアプリを直接起動します。

/Developer/Platforms/iPhoneSimulator.platform/Developer/Applications/iPhone Simulator.app

ちなみに僕のMacはまだ10.5を使っているので、最新のSDKを入れられません。
ゆえに、iPhoneシミュレーターもちょっと古い?ためか実機とCSSの当たり方が少し違いました。

[via]
iPhoneシミュレーターを試す。Safariがサクサク、日本語入力も可 : Media Technology Labs (MTL) : メディアテクノロジーラボ ブログ

Androidシミュレータ

Androidエミュレータのインストール方法

かなり重いが一応Androidのエミュレータ入れたい人向け。
以下の記事を参考にすればできると思います(Mac版)

Android エミューレータで WebKit ウェブブラウザを起動する手順 : Media Technology Labs (MTL) : メディアテクノロジーラボ ブログ
Android 2.1 エミュレータのインストール手順 (Nexus One/HTC Desire) : Media Technology Labs (MTL) : メディアテクノロジーラボ ブログ

ちなみにこのエミュレータのブラウザから127.0.0.1localhostではローカルのWebサーバーに接続することができない。

実はエミュレータ環境からではエミュレータが「localhost」なので、
自マシンには仮想的なネットワークアドレスが振り分けられているそうな


via: 愛は祈りだ [android]エミュレータからホストPCのサーバーに接続する

なので、「http://10.0.2.2/」や「http://IPアドレス」でアクセスする必要がある。

10.0.2.2 Special alias to your host loopback interface (i.e., 127.0.0.1 on your
development machine)
via: Android Emulator | Android Developers

割と楽に確認できるAndroidシミュレータないですかね?

スマートフォン対応サイトのまとめ

こうゆうふうにまとめてくれてるのは本当にありがたいことですわよ!
何か構想を練りたいときは、以下をダラダラ見てると何か閃くかも。

スマートフォン向けなJavaScriptライブラリ

こんだけいろいろとあるとどれが一番いいとかはないとは思いますが、すでにjQueryの知識がある方ならjQuery Mobileが使いやすいと思います。

ホームアイコンをオリジナルなものにする

apple-touch-icon.pngというファイルをサイトのルートに置くか、metaタグへの指定で実現できます。

大きさは57pixel*57pixelがピッタリサイズなのですが、Yahooやアップルなどは129pixel*129pixel程度に作っておき、高精度のアイコン表示を行っています。なお、角丸やテカリ処理はiPhone側で自動で行ってくれます。


via: WebのスキルでiPad/iPhoneアプリ風のWebアプリ作成のまとめ|本を買わずに解決するWeb制作の小技

フルスクリーンモードにする

Webクリップから起動すると「ブックマーク追加」などがあるツールバーを非表示にできます。

またこのタグを指定した場合に、window.onorientationchangeがうまく発生しないという記述が以下のリンクに書いてあるが、iPhone3G(iOS4.2.1)ではうまくfireされた!
画面表示関係 - iPhone 3G DevWiki

さらに以下の記事がちょっと目からウロコだったんですが、Webクリップから起動した際に、aタグで画面遷移しようとするとSafariが起動しちゃう問題に書かれているんですが、これまったくもって知らなかったです。
あと、戻るボタンとかが非表示になっているので、戻るボタン必須だよね!という話もされています。

戻るボタン問題のほうはなんとかするとして、aタグの問題はjQuery Mobileを使っていれば大丈夫だと思います。
jQuery Mobileはaタグのclickイベントにフックして、外部リンクやrel="external"なリンクの場合には、location.href = urlとしてくれているので、Safariが起動しちゃうことはなさそうです。
このlocation.href = urlというところがポイントみたいです。

スマホサイト:Webアプリモードで意外と書かれていない落とし穴 - Kaleidoscope

ステータスバーを黒または半透明にする

Webクリップから起動すると「キャリア表示」などがあるステータスバーを黒または半透明にできます。
指定できるのは以下のいずれか。

  • black
  • black-translucent
  • default

このタグはフルスクリーンモードにするで解説したタグと合わせて使うみたいです。

[via]
画面表示関係 - iPhone 3G DevWiki

URL - 検索バーを消す方法

アドレスバーを消す方法が、window.scrollToでY軸方向に1pxずらすのが主流っぽい。

こんな感じでonload時とonorientationchange時に毎回scrollToしてあげればうまいことアドレスバーが隠れてくれた。
また、jQueryMobileを使うとonload時にscrollToしてくれるが、onorientationchange時にはしてくれてないみたいなので、自分でイベントをセットする必要があるかなー。(jQuery Mobile v1.0a3)

[via]
iPhone Webアプリテンプレート(CSS Nite Vol.40 reprise) | KAYAC DESIGNER'S BLOG - カヤックの意匠部によるデザインやマークアップの話

数字を電話番号のリンクにしない

iOS 4.2.1
OK
Android 2.1
NG

iPhoneのSafariの挙動で、数字を自動的に判別し電話番号とみなす場合があります。
ただし、これは電話番号だけではなく小数点(3.141592)やIPアドレス(192.168.1.1)なども電話番号とみなして、リンクにしてしまうようなので、これを防ぐために以下のようにmetaタグで無効にしておいて、

telto:で明示する方法がよさそうです。

[via]
ウノウラボ by Zynga Japan: iPhone向けのサイトを作るときのちょっとした気配り

タップされた場所をハイライトする

iOS 4.2.1
OK
Android 2.1
OK

これを使うか使わないかでかなりユーザビリティが変わってくると思います。
タッチしたときに該当リンクをハイライトしてくれるので、誤って他のリンクをタッチしてしまうミスを防ぐ手助けをしてくれます。

[via]
ウノウラボ by Zynga Japan: iPhone向けのサイトを作るときのちょっとした気配り

iPhone4の解像度に画像を対応させる

iPhone4はiPhone3GSよりも解像度が2倍のため、等倍の画像がぼやけて表示されていまうことがあります。
これを解決するために、

  • 画像を2倍のサイズで作っておいて、半分のwidthとheightで表示する(3GSに重いサイズの画像をダウンロード意味がない)
  • 3GSの場合は等倍サイズ、4の場合は2倍のサイズを半分で表示する(CSS3のメディアクエリを使う。ちょっとだめ面倒かな)
  • 我慢する

以下のリンクでかなり詳しく書かれているので、どういった方法を採用するかと考える必要がありますね。
小さい画像でしたら等倍でもあんまり気にならないかもしれませんが、少し大きめなバナーの場合はこういった手法を考慮する必要があるかもです。

【Webアプリ】iPhone4 で画像をきれいに表示する色々な方法【試行錯誤編】 | KAYAC DESIGNER'S BLOG - カヤックの意匠部によるデザインやマークアップの話

MobileSafariでposition:fixedがうまく機能しない

どうもiPhoneのSafariでposition:fixedが効かないみたいです。
たしかに、いろんなサイトをiPhoneで見ているとfixedではなく追従ふんわり消してからふんわり表示する方法を採用しているところが多いです。

以下にこの現象のことが書かれていて、
MobileSafariのposition:fixedが厄介すぎる件 - capeknote

  • iscroll.js をつかう
  • Sencha Touch (Ext.js 有料) をつかう

という案があるそうです。

iScrollはデモを見ればそのすごさが分かりますが、Senchaのほうは試していないのでよくわかっていないです。

個人的には、jQueryMobileの機能で代用するのがいいんじゃないかな〜と思っています。
jQuery Mobile: Demos and Documentation

作りこんでいくと常に検索ボタンを画面に表示したいなどの要望が出てきそうなので、この問題にいずれぶち当たりそうですね。

追記:2011-03-02

YUIを使ったパターンが書かれていました!
またこの記事の紹介もしていただきました。ありがとうございます!
YUIライブラリのScrollViewウィジェットを使ってiPhoneでもposition:fixed;が効いてるっぽく見せる - かちびと.net

スマホサイトはリキッドレイアウトがオススメ!

ラッピング要素をoverflow: hiddenにするとiPhoneはハミ出た部分が無視されますが、Androidだと押し広げてしまうケースがあるようです。
基本的な対応は以下のような感じになるのかな〜と思っています。

  • リキッドレイアウトにする
  • viewportの指定をwidth=device-widthにする(Androidブラウザでviewportのwidthの数値指定は効かないので)

■参考リンク
スマホサイトの作り方で、あんまり書かれてないことを書いてみた - iPhone・Android・WEB・音楽制作|Kaleidoscope
Androidにおけるコンテンツフィットと「overflow:hidden」[to-R]

Android2.1でアニメーションgifが再生されない

Android2.1までは内蔵ブラウザでアニメーションGIFが再生できません


via: ブラウザでアニメーションファイル(GIF)をJavaScriptを用いて再生する方法 | GREE Engineers' Blog

とのことで、これをすんごくがんばったのが以下の記事。
アニメーションGifのひとつひとつの画像をバラして、順番に自力でアニメーションさせるというシロモノです。かなりすごい!

ブラウザでアニメーションファイル(GIF)をJavaScriptを用いて再生する方法 | GREE Engineers' Blog


jQuery Mobileについて

ではここからjQuery Mobileのお話。

すでにjQuery Mobileの解説はいろんなブログでされているので、基本的なことよりちょっと気になる感じのことを書いてみようかと思います。
何か間違いがあれば、hisasann on twitterで教えていただければ助かります!

format-detectionをtelephone=yes、またはそもそも指定していないのに自動で電話番号にならないケース

や、そもそもformat-detectionの指定をしていないのに自動で電話番号にならない場合があります。

jQueryMobileを使っていると画面遷移がAjaxを使ってHTMLを読み込むこと多いと思いますが、
この遷移先のHTMLの中に電話番号っぽい表記があって、それをDomに追加した場合にうまく自動で電話番号リンクにならないようです。
どうやら一番初めの画面描画時だけにこの電話番号自動リンク機能が実行されるようです。

なので、これはちょっとハマるポイントですね。

mobileinitイベント

jQuery Mobile: Demos and Documentation

mobileinitイベントはjQuery Mobileが初期化し、画面の装飾をする前のタイミングでfireされるイベントになります。
なので、文言などを変える場合は、このタイミングになります。

デフォルトBackボタンの文言変更する

デフォルトBackボタンを消す

Ajax時の読込中のメッセージを変更する

Ajaxでダイナミックにページを読み込んだ場合のimgのsrc先は?

例えば、

index.html
page/page.html
img/1.jpeg

こうゆうフォルダ構成だった場合に、index.htmlからpage/page.htmlをajaxで読み込んでindex.htmlの中にpage/page.htmlのdata-role="page"の部分を挿入するとします。
そしてpage/page.htmlからimg/1.jpegを読み込んでいたとします。

この場合、カレントディレクトリはindex.htmlが置いてあるディレクトリですが、読み込んだpage.html側からすれば「../img/1.jpeg」の場所に画像ファイルがあるんです。
これはなかなかやっかいな問題ですが、jQuery Mobileはそれとなく対応してくれています。

$.mobile.changePageメソッドの中に

というコードがあり、baseタグに対応していない場合に各hrefとsrcを書き換えてくれます。
ちなみにFirefox3.6で試してみたらbaseタグに対応していなかったです。

なので、
Webkitの場合は、


Firefoxなどbaseタグに対応していないブラウザの場合は、

と書き換えられるようです。

一点問題があるとすれば、htmlコード上にbackgroundで画像を指定した場合にうまいことURIのreplaceが効かないことですかね。
(だから画像の角丸とかを作りたいときに困るかもしれません)

これは今後改善されていくのかな。。。

Android2.1でアニメーションgifが再生されないがAjax時のローディングgifは再生しているじゃないか!について

これは「ajax-loader.png」をCSS3のアニメーションでクルクル回しているだけ。
さすが、jQueryMobile!カシコイ!

該当箇所のCSSはこちらです。

まぁ、そうですよね。

■関連リンク
CSS3アニメーションのおさらいとローディングアイコン :: 5509

デザインは独自のを使いたいんだけど、リンクなどは自動的にAjaxで遷移してほしい場合

今後やり方が変わるかもしれませんが、今のところはこれでイケるっぽい。

jQuery MobileのUIはとてもすばらしいですが、これをいろんなサイトで使うとしたらどれもこれも似たようなサイトが出来上がってしまうので、
サイトのデザインは独自にしたい場合にこうゆう方法が必要になってきます。

  • data-role="page"を付けておけば、aタグなどは自動的にAjaxによる遷移になります。
  • jQuery Mobileに装飾されないようにするために、data-theme="hoge"のようにdata-themeを存在しないものにします。
  • input type="text"にdata-role="none"を付けておく。これしないと勝手にかっこよくなっちゃいます。

或いは、必要なCSS意外をjQuery MobileのCSSファイルから削除しちゃうとか。
でもこれだとあとあとデザインもjQuery Mobileのを使いたいという場合にちょっと不便ですね。

$.mobile.changePage()を使ってページ遷移を独自にしたい!

これは意外とこの需要はあるんじゃないかなーと思っています。
jQuery Mobileに出来る限り依存したくないけど、$.mobile.changePage()を使ったページ遷移は非常に使いやすいので
この部分だけを使いたい場合など。
(そもそもjQuery Mobileの主要機能って$.mobile.changePage()ですよね!)

まずは自動でaタグにAjax処理をbindしちゃうので、それをしないようにします。

そして1ページ目の進むボタンと2ページ目の戻るボタンにイベントを貼ります。

これで進むのほうは、進むトランジションで。
戻るのほうは、ちゃんと戻るトランジションになります。

ハマりやすいのは、2ページ目の戻るイベントを2ページ目のhtml(headとか)に記述しちゃうことです。
2ページ目のdata-role="page"の中に戻るボタンのイベント用のscriptタグを用意すればいいのかもしれませんが(もちろんliveで)、
基本的には1ページ目に2ページ目のボタンのイベントも用意しちゃう感じだと思います。
これみなさんどっちでやってるのかな?

JavaScripから要素を追加した場合に再装飾するにはどうするの?

たとえば独自なAjaxで取得してきたHTMLを画面に追加して、その要素にjQuery Mobileのテーマで装飾して欲しいなんてことがあるとは思うんですが、
こうゆうのは公式デモサイトではサンプルがなくてちょっと困ります。

こちらの内容を参考にしようと思ったんですが、page()というのがどこのpage()なのか分からなかったです。
JQuery Mobile Alpha2(とちょびっとAlpha3)でサンプルサイト制作練習をした。(1) - いちてく

ボタンの装飾

リストの装飾

これはliだけをDomに追加して、ulのlistview()を実行してもダメでした。
ul本体から作り直せばうまいこといきました。

なんとなくこのへんのメソッドの感じから言うと、画面ロード後にHTML要素を追加することをあんまり想定していない?んですかね。。。
結構分かりづらいです。

追記:2011-03-01

HTML5に詳しい吉川さんにTwitterで教えていただきました。
Twitter / @Toru Yoshikawa: @hisasann ブログのほう面白く拝見させて頂き ...

page()というのは、$('#page-id').page()のように呼ぶみたいで、
jQuery Mobileのセレクトボックスを作る$.mobile.selectmenuの中でダイアログを装飾するところで使用されていました。

使い方は、以下のようにまずはHTML文字列を作成して、どこか画面にappendし、page()を実行すれば装飾されるようになります。

また、↑のほうで、Listはulから作らないとうまく再構築できないと記載していましたが、

のようにliを追加した後にlistview('refresh')を実行したらうまく再構築されました。
ただ、Listに1つしか要素がない状態で上記コードを実行すると、角丸のところがまだちょっと変な感じになりました。
このあたりは今後のバージョンアップで改善されていくんでしょうね。

なので、

  • Listだけの装飾であれば、listview('refresh')
  • HTML文字列を装飾するのであれば、$("<div>なにかしら</div>").page()
  • Buttonだけの装飾であれば、buttonMarkup()

という感じですかね。
まぁ、面倒だからどのパターンでもpage()を使いそうですがw


追記:2011-03-11

コントロール要素の強化(enhanceControls)をしたくない場合

jQuery Mobileは使うんだけど、

  • 勝手にテキストボックスやセレクトボックスなどのコントロール要素の装飾をしたくない。やめてっ!

という場合があったりします。

これは、たとえ

のように存在しないdata-themeを指定してもコントロール要素は装飾されてしまいます。

こうゆうときにv1.0a2バージョンまでは$.page._createで行われる_enhanceControlsメソッドの呼び出しをコメントアウトするしかなかったんですが(多分!)、v1.0a3からは$.mobile.page.prototype.options.keepNativeという「なんにも装飾しないでねセレクター」プロパティが追加されています。

使い方は

でkeepNativeとしてのセレクターを指定しておきます。

あとは、各コントロール要素にclassでdata-role-noneを追加すればOK!

これ地味に便利!じゃあの。

スマートフォン参考書籍

HTML5+CSS3で作る  魅せるiPhoneサイト  iPhone/iPad/iPod touch対応
谷拓樹
ラトルズ
売り上げランキング: 945

僕はこちらの本を読まさせていただきました!

ひと通りのスマートフォンサイト構築のお作法や、CSS3を使ったデザインの仕方など、かなり詳しく書かれています。
これで2,310円はけっこう安いですね。

まとめ

今後に期待しまくりなjQuery MobileのちょっとしたTipsを書いてみましたが、まだ分からないことがいっぱいあるので、
今後この記事に追記していこうと思っております。

また、以下にとりあえず目を通しておいたほうがよいと思った記事をリストアップしました。

Beta版まだかなー!!

HTML5とCSS3だけでLightbox - Pure CSS3, no javascript!!

HTML5 Pure CSS Lightboxを見てて、そういえばどうやってやってるか知らないな〜と思い自分なりに簡略化したデモページを作ってみました。
なるべく必要なスタイルだけを使うするようにしています。

CSS3の部

アニメーションは-webkit-animationを使っています。

HTML5の部

Sample1〜Sample4までが画像で、Sample5がテキストになっています。

デモサイト

WebkitGoogle Chromeで見るともれなくアニメーション機能が付いてきます。
CSS3 Lightbox Sample

また、HTML5のタグは以下のリンクを参考にさせていただきました。(すごく見やすい!)
ありがとうございます!
HTML5リファレンス

■関連リンク
animation-timing-function-CSS3リファレンス
animation-direction-CSS3リファレンス

gitをブラウズするのに最適な「tig」をMacportsから入れてみた

gitをブラウズするのに最適な「tig」をMacportsから入れてみた

コンソールから使える git ブラウザ、tig が超便利 - って、なんでですか〜 - subtechを読んで、普段あんまりgitでソースを管理していないんですが、gitのログがかっこよく閲覧できそうなので試しにtigをインストールしてみました。

んで、Macportsにあるかな〜と思って探してみたら、

$ sudo port search tig

tig @0.16.2 (devel)
A text interface to git repositories

あるじゃない!あるじゃない!
ということなので、

$ sudo port install tig

ってやってみたら、以下のようにエラーが出ていっこうに進みません。(多分このエラーはそうそう起きるものではないとは思います)

$ sudo port install tig
---> Computing dependencies for tig
---> Dependencies to be installed: git-core curl curl-ca-bundle p5-error python26 gdbm rsync popt
---> Verifying checksum(s) for curl-ca-bundle
Error: Target org.macports.checksum returned: certdata-1.67.txt does not exist in /opt/local/var/macports/distfiles/curl
Error: Failed to install curl-ca-bundle
Log for curl-ca-bundle is at: /opt/local/var/macports/logs/_opt_local_var_macports_sources_rsync.macports.org_release_ports_net_curl-ca-bundle/main.log
Error: The following dependencies were not installed: git-core curl curl-ca-bundle p5-error python26 gdbm rsync popt
Error: Status 1 encountered during processing.
To report a bug, see

そもそもgitはMacportsから入れていないので、そのあたりかなと思いgitのインストールを試みても同じエラーがでる。
んで以下の記事を参考にしていたらcleanというコマンドを発見!

setup_osx.wiki - bear-project - Project Hosting on Google Code
MacPortsでインストールするときにChecksumエラーが出る場合の対処方法 - yinkywebの日記

おりゃ!!

$ sudo port clean curl-ca-bundle

結果、すんなりtigのインストールに成功しました!

でもまだgitのパスがまだ古いほう(Macportsで入れてないほう)を見に行ってしまうので、
/etc/paths.dディレクトリ内にあるgitファイルの中身を書き換えました。

vim /etc/paths.d/git
/opt/local/bin/git

これに関しては、以下の記事がなかったら、分からなかったよ。
最近のMac OSXで、PATHをスマート(?)に管理するやり方。 - こせきの技術日記
Mac OS X に於ける Path の追加方法 : Sadayuki の Blog

これでようやく

$ git --version
git version 1.7.3.2

と最新のgitを見に行ってくれるようになりました!

tigを使うにはgitで管理しているディレクトリに移動して、tigコマンドを実行するだけ。

$ cd /hoge/code/
$ tig


あとは適当にタイプしていけば慣れてくるのかな?
いろいろ試してみたいと思いますっ!

k
Move cursor one line up
j
Move cursor one line down.
m
Switch to main view.
Tab
Switch to next view.

[via]
The tig Manual

操作方法についてはこちらの記事がすごい参考になります!
CUI な Git ブラウザ tig を入れてみた - Born Too Late

■gitの関連記事
せっかちな人のための git 入門 - git をインストールし、共同で開発できる環境を整えるまで : 僕は発展途上技術者
Git入門 ゼロから始めるGitドリル-エンジニアは空を飛ぶ

入門git
入門git
posted with amazlet at 12.01.27
Travis Swicegood
オーム社
売り上げランキング: 24084

XMLHttpRequest level2に対応しているブラウザまとめ

XMLHttpRequest(Ajax)はもともとは他のドメインへのリクエストは出来なかったのですが、結構前2009年の8月ぐらいにW3Cのドラフトが出てそれ以来各ブラウザが搭載し始めているのが現状。
XMLHttpRequest Level 2

とりあえず対応しているブラウザをちょっと調べてみましたので、メモメモー!

今回は僕が使っている2つのドメインをサンプルとして使っています。
もし、ためされる場合は適宜ご自分のドメインに読み替えてください。

.htaccess

まず
「http://lab.hisasann.com/XHR2/」
の配下に「.htaccess」ファイルを用意して、

Header append Access-Control-Allow-Origin: *

と書いておきます。
これでどこからXMLHttpRequestでアクセスしてきてもOKだよ〜という意味になります。
(ローカルファイルからでもOKです)

それだとちょっと実験としては面白くなかったので、以下の別のドメイン「http://hisasann.sakura.ne.jp」からのアクセスだけを許容するように設定してみました。

Header append Access-Control-Allow-Origin: http://hisasann.sakura.ne.jp

つまり
http://hisasann.sakura.ne.jpからhttp://lab.hisasann.com/XHR2/に対してXMLHttpRequestでアクセスするという感じになります。

json.json(サンプル用json)

先ほどの.htaccessと同じディレクトリにjson.jsonというサンプル用のjsonを置いておきました。

{
"test": "ほげほげ"
}

XMLHttpRequestのサンプルコード

どうもIE8だけはXMLHttpRequestではなく、独自のXDomainRequestというのを使わないといけないみたい。

各ブラウザの対応表(2010-11-16現在)

以下のURLに各ブラウザでアクセスしてみました。

http://hisasann.sakura.ne.jp/XMLHttpRequest2.html

その結果が以下の表です。
結構対応しているんですよね!!

Mac

Firefox3.6.12
OK
Safari5.0
OK
Chrome 7.0
OK
Opera10.10
NG

Windows

Firefox3.5.9
OK
Safari5.0
OK
Chrome 7.0
OK
Opera10.10
NG
IE8
OK
IE7
NG
IE6
NG

ちなみにIE8でブラウザモードをIE7にしても、XMLHttpRequestでアクセスできちゃうのねんっ!
IETesterのIE7でアクセスしたらちゃんとアクセスが拒否されました。

■関連記事
XML Http Request Level2 の噂を聞いたので調べてみた
XMLHttpRequest Level 2 と wedata バックアップ - 0xFF

各ブラウザのオートコンプリート機能が働くパターンのまとめ and デモ

オートコンプリート機能は各ブラウザが搭載している機能ですが、ID・パスワードを保存するときに表示される保存ダイアログの挙動がよくわかっていなかったのでいろいろ試してみました。

基本的にはテキストボックスを2つ持つformがあり、このformを以下の4つのパターンでsubmitさせた場合に、保存ダイアログが表示されるのかされないのかの検証になります。

普通にsubmitボタンでsubmitする場合

ごくごく一般的なパターンで、IDとパスワードを入力するテキストボックスがあって、submit用のinput type="submit"なボタンが置いてあります。
submitボタンをクリックするとどのブラウザでも、保存ダイアログが表示されました。

リンク経由でJavaScriptからsubmitボタンでsubmitする場合

aタグをクリックしたタイミングで、submitボタンをJavaScriptからclickするパターンです。
JavaScriptから実行しているので、一見すると保存ダイアログが出ないかと思われますが、ちゃんと表示されます。

リンク経由でJavaScriptからform.submit();でsubmitする場合

今回の検証で唯一この方法だけが、うまく保存ダイアログが表示されない場合がありました。
IE7、8で試したら保存ダイアログが表示されずに画面遷移しちゃいました。

imageボタンでsubmitする場合

これは1つ目と似ていますが、input type="image"なボタンでsubmitするパターンです。
問題なく保存ダイアログが表示されました。

おまけ:autocomplete属性がoffでも保存ダイアログが出てしまう場合(つまりautocompleteに対応していない)

ブコメで

autocomplete=offとかの検証はないのかなー

とご意見をいただいたので、一応追記しときます。

autocomplete属性をoffにしてもダイアログが出ちゃうブラウザを調査しました。
結果的にはMacとWindowsのOperaが対応していなかったです。

■参考リンク
4.10.7.2 Common input element attributes -- HTML5 (Edition for Web Authors)


詳しくは以下のデモを参照ください!!
オートコンプリート機能が働くパターンのまとめ and デモ

以下いろいろ備忘録

formのactionで、index.htmlからindex2.htmlに遷移している理由

Chromeだとformのactionが現在開いている画面と同じURLの場合?に保存ダイアログが出なかった。
ゆえに、今回のデモではすべてindex2.htmlという2ページ目に遷移するようにしている。

Operaはどこにパスワードを保存してるの?

「環境設定→認証管理タブ→認証管理ボタン」

認証管理マネージャ.jpg

Google Chromeはどこにパスワードを保存してるの?

「環境設定→個人設定タブ→保存したパスワードを表示ボタン」

キーチェーンアクセス.jpg

つまりキーチェーンアクセスに保存されます。
オシャレですね〜!

Safariはどこにパスワードを保存してるの?

「環境設定→自動入力タブ→ユーザ名とパスワードの編集ボタン」

Safari.jpg

僕の環境だと保存したデータの削除を実行する「取り除く」というボタンが効かなかったです・・・ナンデだろう。

Firefoxはどこにパスワードを保存してるの?

「環境設定→セキュリティタブ→保存されているパスワードボタン」

保存されているパスワード.jpg


こんだけMac版とWindows版のブラウザを行き来するとワケがワカメになっちゃうよ...

■関連記事
Internet Explorer のオートコンプリートの動作について
オートコンプリート - Opera Wiki
過去に入力した物でオートコンプリートしたい - Opera Wiki
usoAutoCompleteFromHistory - 工房らくだ舎

TextMateでPHPコードを実行するショートカットは「Shift + Command + R」

もうね。今のいままで知らなかったのよ。

まさかShift押しながらとはっ!

RubyPerlPythonなどはTextMate上で即座に実行するには、Command + RでOKでした。

この流れでPHPもCommand + Rなのかな〜と思ってたんですが、言語をPHPにして実行するとファイルを保存するダイアログが出るんです。
なので、PHPはTextMateでは即座に実行ができないと思って、わざわざ/Site/ディレクトリにファイルを置いて確認してましたよ!


んで、久々にPHP書こうかな〜って思ってバンドルのところを見てみたらなんとありましたよ!

TextMateでPHPコード実行するのは「Shift + Command + R」

Runするコマンドがっ!
何事も知るということがとても大切なんだと思った今日このごろです。

■関連記事
TextMateにZen-Codingを導入して遊んでみる
TextMateのGetBundleがうまくいかないときの対処方法
Railsに最適なテキストエディター「TextMate」を入れて日本語化してみた

MacOSXでnode.jsをインストールする方法(MacPortsが楽チンだよ)

ちょっと今更感がありますが、MacPortsを使ったnode.jsのインストール方法をメモメモ。。。

MacPortsからnode.jsを入れる

MacPortsを使ってインストールすると結構時間が掛かるけど、一発でスルッと入ってくれるのがすごい便利!

$ sudo port selfupdate

Warning: port definitions are more than two weeks old, consider using selfupdate
---< Updating the ports tree
---< Updating MacPorts base sources using rsync
MacPorts base version 1.9.1 installed,
MacPorts base version 1.9.1 downloaded.
---< MacPorts base is already the latest version
$ sudo port install nodejs

---< Computing dependencies for openssl
---< Fetching openssl
---< Attempting to fetch openssl-1.0.0a.tar.gz from http://distfiles.macports.org/openssl
---< Verifying checksum(s) for openssl
---< Extracting openssl
---< Applying patches to openssl
---< Configuring openssl
---< Building openssl
---< Staging openssl into destroot
---< Computing dependencies for openssl
---< Installing openssl @1.0.0a_0
---< Deactivating openssl @0.9.8l_0+darwin
---< Activating openssl @1.0.0a_0
---< Cleaning openssl
---< Computing dependencies for nodejs
---< Fetching nodejs
---< Attempting to fetch node-v0.2.2.tar.gz from http://distfiles.macports.org/nodejs
---< Verifying checksum(s) for nodejs
---< Extracting nodejs
---< Configuring nodejs
---< Building nodejs
---< Staging nodejs into destroot
---< Installing nodejs @0.2.2_0+ssl
---< Activating nodejs @0.2.2_0+ssl
---< Cleaning nodejs
$ node -v
v0.2.2

サンプルコードを動かしてみる

[via]
node.js

↑のjsファイルを保存して、以下のようにnodeコマンドにファイル名を渡します。

$ node example.js

あとはブラウザでhttp://127.0.0.1:8124/にアクセスするだけ!

これで簡単にサーバーサイドJavaScriptを体感できるし、WebSocketだって遊べちゃう。
Jettyを使ってWebSocketで遊んでもいいけど、環境的にはnode.jsのほうが楽チンそう。

Enjoy!! server side JavaScript.

■関連リンク
node.js
HowTo: Install node.js on Mac Snow Leopard with Express : Florian Kubis
[メモ] サーバサイドJavascriptのNode.jsをOSXにインストールする。 - @masuidrive blog
噂のnode.websocket.jsでサーバサイドJSとHTML5 WebSocketを体験してみたの巻 - ダウンロードたけし(寅年)の日記
nodejs | Google グループ
node.jsってなんだね。 - futa.ro | blog

Rubyの形態素解析「MeCab」で文章から名詞を抽出してみる

ちょうどこちらでbotを作ったので、Wordpressを使っておすすめ記事をレコメンドするTwitterBotを作ってみた、形態素解析なんてものを導入したらもっと面白いのかな〜と思って使ってみました。
(実際にbotに導入するかは分かりませんがねっ!)

MeCab本体のインストール

RubyでMecabを使ってみた (Mac OS X) - F.Ko-Jiの「一秒後は未来」を参考にやってみたら、あっさり入りました。

基本的にはMacPortsからインストールします。

まずはMeCab本体。

sudo port install mecab

この時点で、UTF-8ではないmecab-ipadic(辞書)が入りますがあとあと文字化けしちゃうので、次のコマンドを実行する。

sudo port install mecab-ipadic-utf8

そしてRubyから使えるようにモジュールもインストールします。

sudo port install rb-mecab

これだけだとMeCabがUTF-8じゃないほうの辞書ファイルを見に行ってしまうので、設定ファイルを書き換えます。

sudo vim /opt/local/etc/mecabrc

「ipadic」→「ipadic-utf8」と変更します。

dicdir = /opt/local/lib/mecab/dic/ipadic-utf8

ターミナルからMeCabを使って遊んでみる

ターミナルにmecabと打ち込んでエンターを押して、もう一度エンターを押します。

mecab

そうすると入力モードになるので、適当に言葉を入力してみます。「僕はラーメンが好きです。

EOS
僕はラーメンが好きです。
僕 名詞,代名詞,一般,*,*,*,僕,ボク,ボク
は 助詞,係助詞,*,*,*,*,は,ハ,ワ
ラーメン 名詞,一般,*,*,*,*,ラーメン,ラーメン,ラーメン
が 助詞,格助詞,一般,*,*,*,が,ガ,ガ
好き 名詞,形容動詞語幹,*,*,*,*,好き,スキ,スキ
です 助動詞,*,*,*,特殊・デス,基本形,です,デス,デス
。 記号,句点,*,*,*,*,。,。,。
EOS

なかなか面白いですね〜、文章がうまいこと分割されています。

Rubyを使って文章から名詞を抜き出してみる

RubyからMeCabを使うサンプルは、Browse MeCab Files on SourceForge.netよりモジュールをダウンロードするとtestコードが入っているので、そこを参考にしてもいいでしょう。

このコードを実行すると、以下のように出力されます。

今日

わたし
変態

う〜ん。。。もっとマトモな言葉で使いましょうねっ!

■参考リンク
mecabで『走れメロス』から名詞だけを抽出する - 大切なものは目に見えない - mahataの日記
Rubyで形態素解析してみた - unnecessary words
RubyでMecabを使ってみた (Mac OS X) - F.Ko-Jiの「一秒後は未来」
[-*煙猴*-]: mecab-rubyを使ってみる
[-*煙猴*-]: Ruby+MeCab+MySQLでスクリプト書いた

Wordpressを使っておすすめ記事をレコメンドするTwitterBotを作ってみた - NoTechnoNoLife

haseco氏になんとなくあったら面白いかも!と言われたのでサイトの宣伝がてらに作ってみました。
基本的な機能は、

「@NoTechnoNoLife 宛にキーワードをポストすると、そのキーワードからNoTechnoNoLifeを検索し、オススメの記事をレコメンドするbot」

ですっ!

それっぽく動けばいいや〜と思っていたのですが、いろいろ作っていると面倒なことがちょいちょいあったのでここにメモとして残しておきます。

WordpressにJSONを返すAPIを作成したい!っが・・・

まずはキーワードを元に、該当する記事のタイトルURLを返すAPIを作ります。
はじめ、テーマのディレクトリに適当な名前でphpファイルを置いて、/hoge.phpでアクセスしてみたんですがうんともすんとも言わないので、
MTみたいにデザインのテンプレートにファイルを追加するだけでは作れないんだと分かりました。

必要な作業は、

  • 新規ページの作成(これがAPIのURL)
  • テンプレートにphpファイルを追加(検索機能)

ぐらいです。
もっと他によい方法があるのかもしれませんが、今回はとりあえずこんな感じで行きますよー!

(以下、僕が作成した環境になりますので、適宜自分の好きなファイル名や文言などに置き換えて読んでください。)

Wordpressのテーマディレクトリに.phpファイルを配置する

自分のサーバーのテーマディレクトリに「recommend_entries.php」というphpファイルを作成します。
中身は以下のようにしました。

このTemplate Nameが次のステップのページを作成するときに洗濯するテンプレート名になります。

Wordpressのページを新規作成する

次にAPIとして提供するためのページ(URL)を作成します。
管理画面の左側ペインから「ページ」→「新規作成」で新規作成ページを開きます。

タイトルに「Recommend Entries」と入力して、
属性という表示項目のところのテンプレートを、さきほど作成したテンプレートを指定する。

ページを編集 ‹ NoTechnoNoLife, フェティッシュな情報をあなたに -- WordPress-1.jpg

これでAPIとしての準備はできた!
あとはコーディングだ。。。

記事をレコメンドするphpファイルを書いてみる

このphpファイルがAPIの機能を主に担う。
ここで重要なのが、あるキーワードがこのAPIに投げられたら、そのキーワードを元に本来Wordpressが持っている検索処理を走らせないのだが、
GETパラメータに「s=ほげ」としてしまうとsearch.phpが呼ばれてしまい、このphpファイルが呼ばれない。
これはおそらくWordpressが内部的にこのパラメータがある場合はこのphpとかやってるんでしょうね。

よって、「s」というパラメータは使えないので、今回は「re」を使う。
reを使うんですが、検索機能を使うためにはsにキーワードを入れる必要があるので、結果的に以下のようになった。

さらにちょっとややこしかったのが、Wordpressは特殊文字を実体参照に変換するっぽいので、記事のタイトルに「-(←ハイフン)」があると「&#8211;」に変換されてしまう。
なのでmb_decode_numericentity関数を使って復元している。(PHPあまり分からないのでこれで合ってるのかな。。。)

APIのソースコード

json_encode関数の存在を知らなかったので、普通にJSONを組み立ててたらパースできなくてすごいハマった。。。

テンプレートを参考にすると、the_titleやthe_permalinkなんてタグを見かけるんですが、これは中でechoしているので今回は使えません。
代わりに、get_the_titleget_permalinkを使って取得しています。

この辺のタグについては以下のページが参考になります。
テンプレートタグ - WordPress Codex 日本語版

■GitHub
gist: 612770 - GitHub

Replayを元にオススメするTwitterBotを作る

APIは出来たのであとはbotだっ!(botはRubyで書いてみました。)

twitterというモジュールを使っています。
ちょっと補足として、replayの取得はTwitter::Base.mentionsメソッドを使って取得するんですが、twitter0.7.0にはこのメソッドがないみたいなのでtwitter0.8.0以降をお使いください。

twitterに関しては以下に詳しく書かれています。
Greenbear Laboratory - Ruby Twitter Gem簡易リファレンス

それと事前にTwitter / アプリケーションを登録でbot用にアプリ申請をしておく必要があります。
これをしないとOAuthが使えないので。

TwitterBotのソースコード

5分前よりも後にreplayされていたら、そのtweetからキーワードを抽出して(正規表現分からなかった...)WordpressのAPIに投げ、結果をつぶやく。

■GitHub
gist: 612998 - GitHub

ちなみにcronは5分毎に実行されるように設定しています。
なのでリアルタイム性はちょっと弱いですね。。。

今は単語だけですが、MeCabなどの形態素解析を使って文章の中からキーワードを引っ張り出して検索しても面白いかもしれません。
Rubyで形態素解析してみた - unnecessary words

(サイトに行って検索テキストボックスにキーワード入力すればいいんじゃない?って言わないでくださいね!)

また一つ無駄なものを作ってしまった...

今回の作品

もしよければフォローしてくださいな。
NoTechnoNoLife (NoTechnoNoLife) on Twitter

■参考リンク
僕とヒロムとWEB戦争 » WordPressで従来型のページ作成
Character entity references in HTML 4
WordPress ページテンプレートについて - tail -f /var/log/こうちかずお.log

scriptタグにHTML5からサポートされているasync属性を指定すると読み込む順番を担保しないで実行される

HTML5のscript要素でasync, deferを使ってパフォーマンスアップ - IT-Walker on hatenaこちらの記事を拝見してて、そういえばasync属性は試したことがなかったので、検証したのをメモメモ。
とは言っても、scriptタグにasync属性を付与しただけですが...

現時点でasync属性をサポートしているのは、Firefox3.6参考記事:What is a non-blocking script?)だけのようですので、こちらで試しました。

一応async属性について解説すると、

「スクリプトは利用可能になった時点で非同期に実行されます。」

となっていて、
同じような属性のdefer属性は、

「スクリプトはページのパースが終了したときに実行されます。」

雰囲気は同じように見えますが、実行されるタイミングが違いますね。

[via]
script 要素 - スクリプティング - HTML要素 - HTML5 タグリファレンス - HTML5.JP

async属性を試してみる

4つのscriptを読み込むときに、
3つはasync属性を付与して非同期読み込みを実行します。
1つはasync属性を付与しないで同期読み込みを実行します。

以下のように比較的大きなJSファイルを初め(prototype.js)と最後(jquery.js)に読み込んで、その間にconsole.logしかないJSファイル(a.js)を読み込むようにしときます。

んで、これを実行すると!

1番目:"script on body"
2番目:"a.js"
3番目:"prototype.js"
4番目:"jquery.js"

という順番でコンソールに出力されました!
つまり、async属性がないbody内のscriptが一番初めに実行され、軽いJSファイルのa.jsがその次に実行されたという結果になります。

でも、script 要素 - スクリプティング - HTML要素 - HTML5 タグリファレンス - HTML5.JPここに書かれている「非同期に実行するスクリプトのリスト」をブラウザが内部的に保持しているとしたら、その順番通りに実行されるんじゃないのかな?
ダウンロード処理までは順番で、その後の実行までは管理しないとなると順番がバラバラになるのはなんとなく分かるんだが。。。
ここらヘンはまだ良くわからないですね。

ちなみに他のChrome、Safari、Operaなどで試してみましたが、サポートしていないためなのか、普通に上からscriptを実行していきました。
そりゃそうですねw

Google Analyticsのトラッキングコードでasync属性が使われている

僕は古いトラッキングコードを今だに使っているので、以下のコードは見たことがなかったんですが、

ga.setAttribute('async', 'true');

の部分で使用されています。

そもそもDOMを使ってscriptを挿入しているので、この時点で非同期で読み込まれるから、あんまりasync属性の恩恵は受けないのかもしれないですね。

async属性を記述しているのは明示的に非同期で読み込むことをブラウザに通知するためとGoogle Code Blogには書いてあります。


via: Google Analytics 非同期トラッキングコード再考 | MOL

[via]
Google Code Blog: Google Analytics Launches Asynchronous Tracking

追記:上記リンクにあるトラッキングコードは古かったようなので、以下のリンク先から抜粋させていただきました。
Google Analytics 非同期トラッキングコード再考 | MOL

■関連リンク
動的なscriptタグの読み込みを同期的に行う | Blog.37to.net
外部JavaScriptの動的ロード - 0xFF

ハイパフォーマンスWebサイト ―高速サイトを実現する14のルール
Steve Souders スティーブ サウダーズ
オライリージャパン
売り上げランキング: 11944

HTML文字列に値をバインドしてくれるjQuery Plugin - jTemplete

すでにjQueryのPluginとしてはjTemplates | jQuery Pluginsという立派なプラグインがあるんですが、機能が多いのでもっとシンプルにバインドだけしてくれるプラグインが欲しいと思って結構前に作ったのを公開してみます。
(とはいってもすでに誰かが作っているかもしれませんが。。。)

Ajax後にHTMLをつくり込むときに便利で、ここ最近はこのプラグインを基準にコーディングしています。

jTemplete

サンプルコード

まず$.jTemplateにHTML文字列を渡し、その中に${}を使ってJSONが持つプロパティキーを書いておきます。
そしてevaluateにAjax後に取得したJSONとかを渡して、該当のキーがあった場合に置き換わります。

このHTMLを$("wrap").html(html);とかでDOMに追加してあげればOK!!

たったこれだけの機能しかありませんが、いちいち配列にpushしていって最後にjoinしたり、+で文字列と変数をつなぎあわせたりする必要がないので、意外と便利。
ちなみにこのテンプレートは、prototype.jsのTemplete機能と同等になります。

またuupaaさんが作ったuu.snippetで「やりましょう」、Widgetの作り方入門 - latest logこちらに書かれているヒアドキュメントを使った方法も面白いですね〜!

jTempleteダウンロード

gist: 536988 - GitHub

Wordpressで現在のページ番号と総ページ番号を表示する方法

get_query_var('paged')で現在のページ番号を取得できる。
ただし、1ページ目はなぜか「0」が返ってきてしまうので、0の場合は1を返すようにしている。

また、$wp_query->max_num_pagesで総ページ数を取得できる。

現在のページ番号と総ページ番号を表示するコード(function.php)

上記のコードで、一見すると$wp_query->max_num_pagesの部分もget_query_var('max_num_pages')で取得できそうですが、これはできないみたい。
というのもget_query_varメソッドは$wp_query変数の中にあるquery_varsという配列の中を探しにいくようです。
そしてこの中にpagedがあるので、pagedをさがすことができますが、max_num_pagesはその配列の中には存在しないから取得ができない。

もし$wp_queryの中身を見たい場合は以下のコードを実行すると見やすく表示してくれるので、検証できると思います。

[via]
phpのvar_dump()で表示されるデータをきれいに表示する方法はありますか?データベ... - Yahoo!知恵袋

サンプルコード(index.php)

ページングなどが置かれている場所に配置するなら以下のように書く感じだと思います。

■関連記事
関数リファレンス - WordPress Codex 日本語版

今見ているサイトを短縮URLにしてTwitterにつぶやくブックマークレット

先週末にこのブックマークレットを作ってて、実はbitlyAPIにcallback_methodパラメータを渡せばJSONPになるという驚愕の事実を知ったのですが、自分で作っちゃったのでとりあえずメモ的にエントリー。

サイト見てて、このサイト面白いと思ったら「サイトのタイトル - URL」のようにつぶやく既存のブックマークレットを使っていたんですが、URLの部分が短縮にならなかったので、
ためしに作ってみました。

しかも無駄にRailsでっ!!

bit.lyのAPIについて

bit.lyのAPIを使うにはアカウントを作る必要があるそうなので、作りました。

細かいAPIは以下に書いてあるのですが、
ApiDocumentation - bitly-api - bit.ly REST API method documentation - Project Hosting on Google Code

http://api.bit.ly/v3/shorten?login=hoge&apiKey=XXXX&uri=http://hisasann.com/&format=json

上記の感じです。

ではRubyからbit.lyのAPI経由でURLを短縮します。
パラメータとして、短縮したいURLとcallback関数を渡します。

URLは以下。

http://hisasann.sakura.ne.jp/bitlyJSONP/bitly/convert?url=http://hisasann.com/&callback=hoge

Controllerのコード

短縮されたURLとcallback関数名をインスタンス変数に入れて終わり。

Viewのコード

callback関数にURLを渡すだけのコードを返します。

ブックマークレットJavaScript

http://lab.hisasann.com/bitly/bitly.js

ブックマークレット

以下のリンクをブラウザのブックマークにドラッグアンドドロップしてください。
Tweet bit.ly

一応Rails部分だけgitHubにコミットしときました。
hisasann's bitlyJSONP at master - GitHub

まとめ

Railsのプロジェクトを作成して、さくらにDeployしたんですが、なぜか動かなかったのでsshでログインしてさくらサーバー内で開発しちゃいました。
エラー内容はよく見る以下の感じなんですが、どこをどうしてもダメ。
Railsのバージョンは2.2.2をサーバーとローカルで使っているんですが、Rubyのバージョンがサーバー1.8.7・ローカル1.8.6が原因なのかな・・・
それともパーミッションか。

Application error
Rails application failed to start properly"

すでにあるものを作ってしまいましたが、まあ良しとしますw
でも1つ余計にサーバー介してるので重いですね。

■関連リンク
Rubyでbit.lyのAPI経由で短縮URLを取得する - 黒川仁の文具堂ブログ三昧

MySQL5.0.41でWHERE区にサブクエリがあるとGROUP BYでemptyになる

ハマったので、メモメモ。。。

MySQL5.0.41だと以下のようなクエリはどうやらemptyになるよう。
何か特殊な条件もからむのかもしれないが、詳細は不明

emptyになるパターン

GROUP BYを外すとレコードはあるんだが、GROUP BYを入れるとemptyになる。

結構単純なクエリなのに、ドンハマり!

回避する方法

一緒くたにしたいレコードの内容が一致する前提で、DISTINCTで逃げてみる。


ちなみにMySQL5.0.33ではこのバグは存在せず、GROUP BYがあってもレコードが抽出される。

HTML5のaudio用jQuery Plugin - jAudio

たいしたものではないが、最近HTML5のaudioタグで遊んでいるので、そのためのプラグインを書いておいた。
audioタグのもつメンバもブラウザによってまちまちだったりするので、完璧ではないがとりあえず動くレベル。

たとえばFirefox3.6ではplaybackRateが動かないが、Chrome5では動くなどなど。

プログラムコード

全部のメンバ網羅できてないかもしれないが、だいたいこれぐらいあれば遊べる。
複数のaudioタグを使ってDJなどするときように、prototypeで実装した。

サンプルコード

jQueryっぽくメソッドチェーン仕様。

playingの中はarguments.calleeを使ってループしてますが、これはあくまでもサンプルとしてで、実際には何もしなくてもよい。
上記実装だと10秒後に、また始めから再生する。

低音がなったタイミングとかを取得して、そのタイミングで何かアクションをおこしたりしてみたいんだけど、そんなことできないよな〜。。。

あと、ふと気になったのが、FIrefoxとChromeでデフォルトのボリュームは同じ1なのに、なんかChromeのほうが音量が大きいw

ダウンロード

gist: 337283 - GitHub

デモ

前にspace - HTML5 & CSS3 DEMOで作ったものをjAudioで置き換えてみました。

FirefoxとChromeで違う背景になります。
jAudio - HTML5 audio DEMO

■関連リンク
メディア要素 - 組込コンテンツ - HTML要素 - HTML5 タグリファレンス - HTML5.JP
HTML5.Audio - JavaScriptからMP3再生ライブラリ(HTML5風) Kawa.netブログ(川崎有亮)/ウェブリブログ

jQuery.uniqueのsortOrder関数がかっこいい!!

配列の中から重複した要素を除去するjQuery.uniqueがかっこいいです。
実際には、

document.documentElement.compareDocumentPosition
"sourceIndex" in document.documentElement
document.createRange

のいずれかを持つブラウザを対象としているようです。

ざっくり抜き出してみたのが以下のコード。

サンプルコード

div1とdiv2がいる前提でコードを書いてます。

sortOrder関数にはdocument.createRangeバージョンを設定しています。

解説

まず
[div#div1, div#div2, div#div1, div#div2]

という配列をUniqueSort関数に渡して、sortメソッドを呼びます。

すると
[div#div1, div#div1, div#div2, div#div2]
というふうに重複要素が隣接されます。

あとは配列の前後を比較して等値だったら、sliceで取り除いている感じです。

最終的には
[div#div1, div#div2]
と重複要素がなくなっている!!

2つの要素のownerDocument.createRange()で要素の場所を特定して、compareBoundaryPointsメソッドで比較しているようなんですが、
compareBoundaryPointsメソッドってoffsetTop、offsetLeftをもとに比較しているのかな?

以下を見てもよくわからなかった。。。
range - MDC

Rangeオブジェクトを使って並び替えるのはなんか斬新で面白かったです。

■関連リンク
jQuery.unique(array) - jQuery 日本語リファレンス
sort - MDC

MacOS10.5でMacPortsからSVNを入れる方法

SVNのインストール

まずはMacPortsからインストール。
とっても楽チン!!

sudo port install subversion +mod_dav_svn

とくにエラーが出なかったですが、結構時間がか掛かりました。

SVNリポジトリの作成

ここは僕の場合は以下に作りました。

/Users/hoge/_/dev/svnroot/repos

ではまずSVNのルートディレクトリの作成です。

cd /Users/hoge/_/dev
sudo mkdir svnroot

続いて、SVNリポジトリを作成します。

はじめ以下のように実行していたのですが、どうも僕の環境ではエラーが発生してしまってうまくいきませんでした。

sudo svnadmin create --fs-type fsfs repo
エラー内容
d Mar 17 16:52:24 2010] [error] [client 192.168.11.95] (20014)Internal error: Expected FS format '2'; found format '4'
[Wed Mar 17 16:52:24 2010] [error] [client 192.168.11.95] Could not fetch resource information. [500, #0]
[Wed Mar 17 16:52:24 2010] [error] [client 192.168.11.95] Could not open the requested SVN filesystem [500, #160043]
[Wed Mar 17 16:52:24 2010] [error] [client 192.168.11.95] Could not open the requested SVN filesystem [500, #160043]

なので以下のようにしてみたらうまく動いたのでとりあえずよしとします!

sudo svnadmin create repos --pre-1.5-compatible

Apacheの設定

まずはhttpd.confファイルを開きます。

cd /etc/apache2
vim httpd.conf

LoadModuleが並んでいる箇所の一番下に以下を追加します。

LoadModule dav_svn_module libexec/apache2/mod_dav_svn.so

httpd.confの一番下に以下を追加。

<Location /repos>
DAV svn
SVNPath /Users/hoge/_/dev/svnroot/repos
AuthType Basic
AuthName "Subversion"
AuthUserFile /Users/hoge/_/dev/svnroot/svn_passwd
Require valid-user
</Location>

これにより

http://localhost/repos

がSVNリポジトリの「/Users/hoge/_/dev/svnroot/repos」とリンクします。
お試しとしてBasic認証も設定ファイルに記載したので、こちらのパスワードも設定します。

Basic認証の設定

以下を入力して実行するとBasic認証のパスワードの入力が要求されるので、2回入力します。

cd /Users/hoge/_/dev/svnroot/
sudo htpasswd -c svn_passwd hoge
New password:
Re-type new password:
Adding password for user hoge

これでBasic認証の設定は終わり。

追記:

@hisasann Basic認証の設定のとこ、2回目以降はhtpasswdに -cオプションいらないので注意


via: Twitter / かわ: @hisasann Basic認証の設定のとこ、2回 ...

SVNルートディレクトリの権限の設定

次に、Webサーバのみがリポジトリを読み取れるようにするために以下のように権限を付与します。

cd /Users/hoge/_/dev/
sudo chown -R www:www svnroot
sudo chmod 600 svn_passwd


あとは、システム環境設定の共有で「Web共有」をリブートする。

そして

Revision 0_ _.jpg

のような画面が開けばうまくいきました!!


■参考リンク
Dreamweaver CS4でのSubversionの使用 - パート3: SubversionをサポートするためのApacheの設定 | デベロッパーセンター
構想雑文 : Mac OS X 10.5(leopard)でSubversionセットアップ その2 - livedoor Blog(ブログ)
Mac Ports で Subversionインストール - Get crazy

space - HTML5 & CSS3 DEMO

space.jpg

画像やFlashはいっさい使わずに何か中心に向かってアニメーションするものを作りたいと思って制作してみました。
今回もjsDeferrd.jsを使用。

cho45's jsdeferred at master - GitHub

中心に向かって行くということで、何かが中心にないと面白くありません。
なので、疑似的な太陽をCSS3で作り、そこにHTML5のcanvasが向かって行くという感じになりました。

サンプルコード - CSS3

実はまだこのgradientというCSSプロパティが良くわかっていなくて、Firefoxで出来るけど、Safariでどうやるのかな〜という部分を検証中です。
-moz-radial-gradientというプロパティを使って太陽を描いているんですが、これをWebkitでどう指定するのかが分からない!

なので、mozとwebkitでは別々の背景にしています。

またbodyタグに-moz-radial-gradientを指定するとなぜかうまく円が描かれなかったです。
divを画面のheight、widthに広げてそこにスタイルを当てるようにして回避しました。

あとHTML5のvideoタグも使って音楽を出しています。
使っている曲は、HoldenのA Break in The Clouds - Main Mixです。(怒られたら使用するのやめますw)
宇宙っぽさが演出できる名曲です。


Firefoxで見ていただくのが一番いいです。
Chrome、Safariの場合は円ではなくグラデーションになってます。
以下からどうぞ。
space - HTML5 & CSS3 DEMO

プログラムコード

gist: 331165 - GitHub

squareDeferred

squareDeferred.jpg

なんとなく思い立って、jsDeferred.jsでアニメーションのループがしてみたいってなったので作ってみた。
この手のアニメーションを考えるときは、どちらかというと間違ったコードが面白さを生み出す。
つまり、不意に間違って2回ループしたら面白いや、ストーリーの組み直しなどで型にハマらない動きができたりする。

ここ最近は拙作のaddCommand - jQuery Pluginでアニメーションを書いていたんですが、jsDeferredも便利ですね〜。

処理の割り込みや、setTimeoutで待たせるときに使ったりしてましたが、アニメーションでも十分に使いやすい。

cho45's jsdeferred at master - GitHub

サンプルコード - jsDeferred.js

ストーリーのループは以下のようにfunctionのcalleeを最後のnextで呼ぶようにしてあげてます。
これで疑似無限ループの完成。


あとjQuery1.4以降の機能でeasingをCSSプロパティ毎に指定できるので、それで少し気持ち悪い動きをくわえてみたりしてます。

Firefoxでも頑張って動いてくれますが、ChromeかSafariのほうが軽快に動作します。
以下からどうぞ。
squareDeferred

プログラムコード

gist: 331150 - GitHub

flickrダラ見サイト - flickrer作ってみた

Flickrer-1.jpg

自分がflickrをダラ見することが多いので、それっぽい感じのサイトを自分用に作ってみた。
特に難しいことはしてなくて、

  • $.jOpening
  • $.flickr
  • $.fn.jCurtain

という3つのプラグインを作って制作してます。
あと、miyagawaさんのmiyagawa's jquery-fitimage at master - GitHubを使って拡大画像の調整をしています。

実は単にカーテンのようなスライドを作ってみたくて、何か面白いことできないかな〜と思っていたらflickrでやったらいいかもと思って試しに作ったのがこのサイトになります。
初めのオープニング部分では、左右からラインが伸びてくるのですが、この当たりはFlashを意識して作っています。

今後もうちょい機能増やして、ダラ見しやすくする予定。
autoでスライドしていくとか。

対応ブラウザは以下(試したのが以下w)

  • IE7
  • Safari4
  • Firefox3.6
  • Chrome5


もしよかったら使ってみてくださいな。
flickrer - flickrダラ見サイト

追記:

@hisasann マウスオーバーで画像を読むまでに間が空くのがもったいないので裏で呼んでおいたほうがいいんじゃないかと。


via: Twitter / edvakf

との意見をいただいたので、拡大画像部分の画像を先読みするように修正しました。

Macに複数MySQLをインストールする方法

MacPortsでインストールする方法MacPortsでMySQLをインストール -- BONNOH FRACTION 13や、pkgでインストールする方法素晴らしき哉、人生!: Mac OS 10.5にMySQLインストールを見てみたんですが、どうもこれらの方法では複数のMySQLを同居させるのがむずかしそうだったので、ソースからコンパイルして入れてみた。

そしてうまく複数のMySQLが動いたので、そのときのメモメモ。。。

ソースをダウンロードする

以下のリンクからtar.gzをダウンロードします。

今回僕はmysql-5.0.33をインストールしましたので、適宜自分のバージョンに置き換えて読んでいただけたらと思います。

MySQL :: Download MySQL Community Server

そして適当なディレクトリに解凍する。

tar zxvf mysql-5.0.33.tar.gz

Macだと基本的にmysql-5.0.33.tar.gzをダブルクリックすれば解凍ソフトが起動するので、ターミナルでなくてもOKだと思います。

今回は/usr/local/srcディレクトリに解凍しました。

そしてディレクトリに潜る。

cd mysql-5.0.33

コンパイルする

まずはconfigureを実行します。
このときのコンパイルオプションは結構重要で、とりあえず以下の感じに落ち着きました。

--with-mysqld-user=hogeのところは、Macにユーザ権限でmysqlをソースから(あと、DBD::mysqlも) - Born Neetを参考にして、今ログインしているユーザーを記述してみました。

--prefix=/usr/local/mysql3306は複数のMySQLを/usr/local/に同居させるので、mysqlの後に僕はport番号をサフィックスとして付与しています。

./configure --with-charset=utf8 --with-mysqld-user=hoge --with-unix-socket-path=/usr/local/mysql3306/var/mysql.sock --prefix=/usr/local/mysql3306 --with-blackhole-storage-engine --with-federated-storage-engine

configureがうまくいけば、あとはmakeで終わり。

make
make install

データベースを初期化する

/usr/local/mysql3306/bin/mysql_install_db --user=hoge

もしここで「unknown option '--skip-federated'」のようなエラーが出てしまう場合は、

以下のファイルの

/etc/my.cnf

この部分をコメントアウトしてください。

#skip-federated

[via]
mysql 5.1のmysql_install_dbがこける - うまい棒blog

初期化が終わるとデータディレクトリのvarが作成されます。

/usr/local/mysql3306/var/

そして今回の重要なポイントですが、MySQLを別ポートで複数起動するので、このmy.cnfが1つだとうまくいきません。
my.cnfにportを指定する箇所があるので、別々のMySQLは別々のmy.cnfを見に行って欲しいわけです。

なので、今回は

cp /etc/my.cnf /usr/local/mysql3306/var

を実行してmy.cnfをデータディレクトリにコピーしました。
これで順番的に自分自身のmy.cnfを見に行くようになります。
また、mysql.sockというMySQLが起動したときに作成されるファイルも別々にしたいので、これもデータディレクトリに作ってねっ!と記述しています。
一般的には/tmp/mysql.sockに作成されるようです。

[client]
default-character-set=utf8
#password = your_password
port = 3306
socket = /usr/local/mysql3306/var/mysql.sock

# Here follows entries for some specific programs

# The MySQL server
[mysqld]
default-character-set = utf8
skip-character-set-client-handshake
character-set-server = utf8
collation-server = utf8_general_ci
init-connect = SET NAMES utf8
port = 3306
socket = /usr/local/mysql3306/var/mysql.sock
skip-locking
key_buffer = 16M
max_allowed_packet = 1M
table_cache = 64
sort_buffer_size = 512K
net_buffer_length = 8K
read_buffer_size = 256K
read_rnd_buffer_size = 512K
myisam_sort_buffer_size = 8M

MySQLを起動する

起動コマンドは以下のとおり。

cd /usr/local/mysql3306/bin
./mysqld_safe &

これでバックグラウンドでMySQLが起動します。

ちょっと教えてもらった操作をメモ。
もし以下のように&を付けずに起動した場合、

./mysqld_safe

Ctrl + zで一旦プロセスを落として、

bg

と叩くと

./mysqld_safe &

をしたときと同じ動作になるみたい。

最後に、プロセスが立ち上がっているかを以下で確認する。

ps ax | grep mysql

MySQLを停止する

以下で止まる。

./mysqladmin shutdown --socket=/usr/local/mysql3306/var/mysql.sock

まとめ

これで、もうひとつmysqlを作りたい場合は、「コンパイルする」の部分から--prefixを変えて実行すればよい。

結構手順としては面倒だが、プロジェクトが複数のMySQLを必要としている場合に、この手順が参考になれば幸いです。

■関連リンク
MySQL :: MySQL 5.1 リファレンスマニュアル :: 2.5 Mac OS X に MySQL をインストールする
「Can't connect to local MySQL server through socket」エラーについて
MySQL :: MySQL 4.1 リファレンスマニュアル :: 4.8.3 mysqld_multi(複数の MySQL サーバを管理するプログラム)
MySQL / Mac OS X
Macにユーザ権限でmysqlをソースから(あと、DBD::mysqlも) - Born Neet
MySQL :: MySQL 4.1 リファレンスマニュアル :: 2.4.1 mysql_install_db の実行に関する問題
1台のサーバに複数のMySQLをインストールしてみた。 | RwJ
MySQL :: MySQL 5.1 リファレンスマニュアル :: 2.9.2 典型的な configure オプション
MySQL :: MySQL 4.1 リファレンスマニュアル :: A.4.5 MySQL ソケットファイル /tmp/mysql.sock の保護または変更方法

MacにImageMagickをインストールする方法

いろいろググッた結果、MacPortsからインストールするのが速そう。
ということでまずはMacPortsのインストールから解説します。

すでに入っているかたは、読み飛ばしてください。

MacPortsをインストールする

まずは、Xcode ToolsをMacに付属しているインストールディスクからインストールします。
終わったら、http://svn.macosforge.org/repository/macports/downloads/からバージョンを選んでダウンロードする。

僕のローカルにはすでに、MacPorts-1.7.1が入っていたので、このバージョンでも問題ないと思います。

次に環境変数にパスを追加しときます。

cd
vim .bash_profile

export PATH=/opt/local/bin:/opt/local/sbin/:$PATH
export MANPATH=/opt/local/man:$MANPATH

一応リフレッシュしとく。

source .bash_profile


あとはMacPortsをアップデートしておわり。

$ sudo port -d selfupdate
$ sudo port -d sync


[via]
MacPortsでステキなUNIXツールをインストール - はこべにっき#

ImageMagickをインストールする

ここまで来るとあとは楽チンで、

$ sudo port install ImageMagick

これで終わり!
いろんなものを一緒にインストールするので、だいたい30分くらいはかかるかも。

すでに、MacPortsでインストールされているものを確認するなら、

$ port installed

と叩けば、ゾロゾロと表示されます。

[via]
[を] Mac に ImageMagick を入れた

■関連リンク
新しいMacbook Proにインストールしたものメモ
MacPortsのコマンド逆引き一覧 -- ディノオープンラボラトリ

JavaScript変態複雑化文法最速マスター

Java変態文法最速マスター - プログラマーの脳みそをリスペクト。
JavaScript変態文法最速マスター - 葉っぱ日記をリスペクト。

特に技法的なことではないんですが、functionをいろんなところで絡めてわかりにくくするポイントをいくつか紹介。

if文にfunctionを絡めてみる

単純なifなはずなのに、条件式に即時実行のfunctionを絡めることによってよりわかりにくくできます。
さらにクロージャをreturnして()で実行し、より複雑にする技法もとりいれてます。

for文にfunctionを絡めてみる

そもそもfor文の回りにfunctionを絡めてわかりにくくし、for文の条件式にもfunctionを絡めます。
さらにクロージャをreturnして()で実行し、より複雑にする技法もとりいれてます。

「ちなみにここでやっていることは引数の[1, 2, 3]という配列を受け取って、新しい配列にコピーしてreturnしているだけです。」

出力結果


[1, 2, 3]

Objectに上記やり方を絡めてみる

aというプロパティはただaを返せば終わりなはずなのに、わざわざfunctionでネストしてわかりにくくしています。
bというプロパティは上記if文複雑化for文複雑化を応用して、解読が困難な状態を実現しています。

出力結果


[1, 2, 3]

複雑化で気を付ける点

iをインクリメントする部分の複雑化で

という部分がありますが、ここで

このように引数で渡してはいけません。
外側のスコープにいるiではなく、このfunctionの関数スコープ内のiをインクリメントすることになるので無限ループになります。

これ以外にもcurry化をうまく使いまくって、複雑にすることができますが、だいたい上記のことが応用できれば特に問題はありません。

※注意 function絡めは節度と必要度合いを見て実装しましょうね!

エラトステネスの篩 - JavaScript版

エラトステネスの篩 - Wikipedia

こんな感じなのかな。。

サンプルコード

出力結果

[2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97]

勉強になりました!

JavaScriptライブラリを使っていてIEで余計なリクエストが発生してしまうケース

ここ最近フロントエンドのパフォーマンスチェックでHttpWatchを使っているんですが、これはかなり調子がいい!
特にインストールするとIEとFirefoxに追加され、Firebugのように画面の下のほうに表示されるので違和感なく使えます。

んで、このソフトを使ってサイトのパフォーマンスチェックをしていたら、IEの場合だけ

ERROR_INTERNET_INVALID_URL

httpwatch1.jpg

というRequestの結果が返ってきて、これってなんだろうと調べてみたら、jQueryprototype.jsYUIを使っている場合に
IEでDomContentLoaded(DCL)判定するときに発生しているようです。

これでだいたい3〜6ミリ秒のオーバヘッドがあるよう。
ほんのちょびっとですがねw

jQueryの場合(ver1.2.1)

bindReady関数の中にIEだったらという分岐があり、その中でsrc=//:なscriptタグをdocument.writeしているのが原因。

このscriptがdocument.writeされたタイミングでsrc属性のURLをGETする際に、よくわからんURLじゃ〜と言っているんでしょうね。
jQueryがこの判定方法を使っているのはおそらく1.2.1以前だと思うので、1.2.6や1.3.X、または1.4を使っている場合は問題ありません。

ちなみに1.4のDCLの判定は以下のようになっています。

onreadystatechangeとonload、あとは今までにもあったdoScrollで判定しているようです。

prototype.jsの場合(1.6)

このprototype.jsを使っている場合が、今回のERROR_INTERNET_INVALID_URLなRequestを送信してしまうパターンになります。
実際のコードは以下のとおり。

deferで遅延評価させて、readyStateがcompleteになったらfireしています。
この方法個人的に面白くて好きなんですが、無駄なRequestが発生してしまうのが難点ですね。

■関連記事
Prototypejsのdom:loadedを検証(IEの場合)

YUIの場合

ERROR_INTERNET_INVALID_URL & HttpWatch - HttpWatch BlogにはYUIでも起こると書かれていましたが、YUI2・YUI3の両方でscriptをdeferさせる方法はなかったので大丈夫でしょう。
もっと古い時代に書かれていたと思われます。

以下YUI3のDomContentLoaded判定。

ほとんどjQueryと同じです。

まとめ

今回のERROR_INTERNET_INVALID_URLが発生してしまう可能性があるのは以下、

  • jQueryは1.2.1以前を使っている場合
  • prototype.js1.6以前を使っている場合
  • YUI2よりも前のものを使っている場合

の3点かな。
他のライブラリも含めたらもっとあるでしょうが、とりあえず調べたのはこんだけ。
Firefoxとかだとこの現象は発生しないので、なかなか発見しずらいものではありますが、たまたま発見したのでログとして残しました。

HttpWatch以外に僕が使っているパフォーマンスチェックツールは、

YSlow :: Add-ons for Firefox

page-speed - Project Hosting on Google Code

あと、

Diagnose and Prevent AJAX Performance Issues - dynaTrace AJAX Edition

これIEだけなんですが、CLASS指定の個数とかID指定の個数とかわかるので、どこで遅くなっているかがわかりやすいです。

ではでは。

■関連リンク
ERROR_INTERNET_INVALID_URL & HttpWatch - HttpWatch Blog

JavaScript遅延ロード - jLazyLoader

Gmailチームが明かすHTMLアプリケーション起動の高速化テクニック - TechTalkManiacsを読んでて、こんな方法があるのか〜と関心した。
scriptタグの中をコメントアウトにしているので、初めのJavaScriptが解析されるときは無視されて、あとでevalさせるという面白い方法。

ソースコード

ダウンロード

gist: 270994 - GitHub


コメントアウトにしちゃっているので可読性は低いですが、このテクニックはいつか使って速度の検証をしてみたいところ。

■関連リンク
Google Code Blog: Gmail for Mobile HTML5 Series: Reducing Startup Latency

eclipseの起動画面を変えて楽しむ方法

eclipseたんスプラッシュ画像 - 虎塚を見て、普段使うeclipseの起動画面で遊びたいという欲求が生まれた。

だいたい15秒から30秒くらいしか表示されないeclipseの起動画面ですが、何か自分オリジナルで面白い画像にすると幸せになるかもしれませんね。

以下オリジナルな起動画面いろいろ。

eclipse3.2

splash3.2.jpg

eclipse3.4 - GANYMEDE

eclipse3.5 - GALILEO

splash3.5.jpg


そして、虎塚さんが作った画像が以下。

eclipseたん

splashtan.jpg

eclipseの起動画面を変更する方法

「eclipse/plugins/org.eclipse.platform_X.X.XXX」というディレクトリの中に、splash.bmpファイルがあるので、これを自分の好きな、或いはアレンジした画像に置き換えてあげるだけ。
これで次回の起動のときに表示されます。

かなり簡単ですね。
さぁて、画像作ろう。。。

■関連リンク
世話焼き系IDE:eclipseたん - 虎塚
Eclipse起動時に表示される画像を変更する

Googleのロゴがニュートンになってた。そしてリンゴが落ちてきた

tree.jpg

普段Googleトップをあんまり活用していないのでわからなかったですが、わっきーさんに教えてもらいました。

んで、コード見てたらロゴのimgタグのonloadにリンゴを落とすJavaScriptが書かれててちょっと面白かった。
imgのonload使うときって、あとから読み込んだ画像のwidth・heightを取得するときに使ったりするんですが、こうゆうトリッキーな使い方は面白いですね。

ざっくりですが、コードを抜き出してみたのが以下。

サンプルコード

1個分からないのが、アニメーションのclearIntervalgoogle.reinにpushしているんですが、
これをいったいどこで実行しているんだろう。。。

Googleトップのコードを一通りおってみたんですが、実行してそうな箇所がない。
1つだけあやしい箇所があったんですが、9zPpGAOKyhU.jsの中の以下の部分。(だいぶ端折ってます)

iにはpushという文字が入っているだけで、pushされた分をループしているわけではない。。。

仕方ないので、以下のグリモンでテスト。
タイミングがもしかしたら微妙かもしれないが、リンゴが落ちたあとにclearIntervalされるはずだからonloadでもOKでしょう!

google.rein実行された?グリモン

じっ、実行されない。。。

Firebugのprofileで調査

リンゴが落ちたあとにprofileを開始して、適当なタイミングで止めてみたのが以下の画像。

Google.jpg

undefine()」の部分が、該当のアニメーション処理。
中身を見ると、

とアニメーションのクロージャが入っているので、間違いないでしょう!
profileEndのタイミングをずらせばもっと回数の部分が増えていきます。

結局、よくわからなかったんですが、実行してないでしょ?w
いや〜分からんな〜〜〜。

グーグルのロゴデザインやってる人に
乱歩のやつは最高だったと伝えておいてください

喜ぶと思います。彼はdoodle 作るのにたくさんの資料や本を読んだり、頭があつあつになるくらい考えてますから。
でも手塚治虫先生の時や藤子先生の時など漫画がたくさんおいてあるので遊んでるみたいです。


via: グーグルで働いてるけど何か質問ある? - ブラブラブラウジング

[via]
グーグルで働いてるけど何か質問ある? - ブラブラブラウジング

XCodeでWebkitをデバッグする方法

JavaScriptのDomメソッドがどうやって動いているのか、普段あんまり意識しないですが、気になりだすと調べたくなるものです。

WebkitはSafariやGoogle Chromeに採用されているレンダリングエンジンで、高速でありアニメーションも非常になめらかです。

そんなWebkitをいつでも追えるように、デバッグ環境を作っておくと便利かも?と手順をメモしておきます。
「JavaScripterの参考になればうれしいです。」

XCodeのインストール

XCodeのインストールは、インストールディスクの中にあるOptional Installsフォルダに入っていますので、そちらからインストール可能です。
もしインストールディスクがない場合は、Apple Developer Connection - Mac Dev Centerよりダウンロードが可能です。
ただし、AppleDeveloperConnectionへのログインが必要になります。

[via]
The WebKit Open Source Project - Installing Developer Tools

Webkitのソースコードをダウンロードする

ターミナルを起動して、まずはダウンロード先のフォルダを作成します。

cd ~
mkdir webkit
cd webkit

次に以下を入力するとSVNからダウンロードが開始されます。

svn checkout http://svn.webkit.org/repository/webkit/trunk WebKit

僕は30分以上かかったので、ランチに行くときに実行しておくとよいかもしれません。
また1度目はターミナルが途中で落ちてしまったので、あまり他の作業は行わずソースのダウンロードに専念させてあげたほうがよいかもしれません。

ソースコードのダウンロードが終わりましたら、以下を実行してください。
どうやらこれをしないとビルドがうまくいかないようです。

WebKit/WebKitTools/Scripts/update-webkit

[via]
The WebKit Open Source Project - Getting the Code

Webkitをビルドする

さっそくビルドを開始します。
以下を実行すると、ターミナルが膨大に流れ始めます。

WebKit/WebKitTools/Scripts/set-webkit-configuration --debug
WebKit/WebKitTools/Scripts/build-webkit --debug

ビルドもだいたい30分くらいかかるので、夕飯を食べにいきましょう!

成功すると以下のようにコンソールに表示されます。

Touch /Users/hoge/_/code/webkit/WebKit/WebKitBuild/Debug/WebKit.framework
cd /Users/hoge/_/code/webkit/WebKit/WebKit
/usr/bin/touch -c /Users/hoge/_/code/webkit/WebKit/WebKitBuild/Debug/WebKit.framework
** BUILD SUCCEEDED **

===========================================================
WebKit is now built (32m:39s).
To run Safari with this newly-built code, use the
"WebKit/WebKitTools/Scripts/run-safari" script.
===========================================================

[via]
The WebKit Open Source Project - Building WebKit

Webkitを起動する

WebKit/WebKitTools/Scripts/run-safari --debug

これで今回ビルドした内容でSafariが起動すると思います。
これでテストは完了です。

XCodeを使ってWebkitをデバッグしてみる

ではでは、いよいよWebkitをデバッグしてみます。
今回はdocument.getElementByIdをデバッグしてみようと思いますので、WebCoreあたりを除いてみます。

まずはダウンロードしたWebkitのWebCoreディレクトリをFinderで表示します。
僕の場合は以下のようなパスにダウンロードしました。

/Users/hoge/_/code/webkit/WebKit/WebCore

ここにXCodeのプロジェクトファイル「WebCore.xcodeproj」があると思いますので、実行してみましょう。
起動するとWebCoreプロジェクトが左のペインに表示されます。

ここのWebCoreの部分で右クリックして、「情報を見る」を選択します。

Document.cpp -- WebCore-1.jpg

するとWebCoreの情報が表示されるので、

のように、「カスタムの保存場所」を指定します。
これは実際にビルドされた内容が存在するパスを指定していることになります。

次にアタッチ先となる実行可能ファイルを作成します。

グループとファイル」ペインの真ん中あたりに「実行可能ファイル」という項目があるので、ここを右クリックし「追加」→「新規カスタム実行可能ファイル」を選択します。
以下のようにSafari.appまでのパスを設定します。

これによりデバッグ時にSafariを使う設定が完了しました。

Webkitにアタッチさせる

いよいよデバッグです。
XCodeのメニューにある「実行」から「進行(デバッグ)」を選択し、デバッグモードで起動します。

この作業は少し時間がかかるので、Safariが起動するまで気長に待ちましょう!
ここでどんな作業が行われているかをコンソールから確認することができます。
以下のボタンをクリックしてコンソールを立ち上げてみましょう。

Document.cpp -- WebCore-2.jpg

このように何かしらの作業が進行していると思います。

WebCore -- デバッガコンソール.jpg

Safariが起動したら、ブレークポイントを貼ってみましょう。(ここが今回の穴場です!)

document.getElementByIdにブレークポイントを貼る

左側のペインのWebCoreのdomの下にDocument.cppというファイルがあるので、これをクリック。
すると右側のペインにソースコードが表示されるので、「Cmd + F」でgetElementByIdを検索してみます。
(シンボルを選択するプルダウンからもメソッドを表示することができますが、今回は検索機能を使ってみます。)

すると以下のようなコードにたどり着くと思います。

そうです。これがdocument.getElementByIdの実体です。
普段使いに使いまくってるメソッドを見れるのはうれしいですね〜。

では簡単なHTMLファイルを作ってデバッグしてみましょう!

デバッグを貼るポイントはとりあえず、以下のifのところにしてみましょう。

すると以下のようにブルーのしおりのようなものが表示されるので、これがブレークポイントになります。

Document.cpp -- WebCore-3.jpg

これで先ほどのHTMLファイルをSafariで開いてみますが、まだアラートは表示されません。
document.getElementByIdにブレークポイントを貼っているので、アラートが表示される前にデバッガがWebkitの実行を待ち状態にしています。

デバッガを使ってみる

ここで便利なのがデバッガです。
デバッガは以下のようにボタンになっているのでクリックすれば起動されます

Document.cpp -- WebCore-4.jpg

HTMLファイルを開くとブレークポイントのところでストップします。
あとはステップオーバーしたり、ステップインしたりして遊んでみてください。

変数の監視でelementIdを見ることは出来るのですが、UChar *を16進で表示しているので本当にgetElementByIdで渡した文字列が入っているのかが確認できません。
バイナリから判断することはできるのですが、デバッガウィンドウに直接文字列が表示してほしいところです。
値を他の形式で表示してもうまくいかないので、ここは後で調査します。

Windowsでのデバッグについて

今回はMacのXCodeを使ってWebkitをデバッグしてみましたが、もちろんWindowsのほうでもデバッグは可能です。
手順は以下のリンクに詳細が載っていますが、Mac版とくらべてややこしそうです。

VisualStudioをインストールして、さらにパッチなども当てなくてはいけないので、サクッと試したい場合はMac版のほうが簡単そうです。

WebKitビルドガイド(ドザー用) - 最速チュパカブラ研究会

まとめ

document.getElementByIdを追ってみましたが、何度か実行しているとあることに気がついてきます。
elementIdより該当のidを持つエレメントを探しにいくんですが、m_elementsById.get()を実行してすでにモジュール変数にエレメントがある場合は検索処理をスキップします。
つまりサイトを開いて、Cmd + Rを押すとすでにm_elementsByIdにエレメントが入っているので、高速に動くみたいですね。
こうゆう情報は実際に追ってみないとなかなか分からないものです。

ソースコードも膨大ですが、XCodeでのビルドも結構時間がかかりますが、今後面白い内容が発見できたらブログにアップしていこうと思います。

■参考リンク
[Tips] Xcodeでプログラム実行と同時にコンソールウィンドウを表示させる方法 - Ni chicha, ni limona -平均から抜けられない僕-
Mac OSX Build and Run! Xcodeの入手方法

TumblrからランダムにURLを取得してTwitterにPostするbotを作ってみた

自分のTumblrからランダムに1時間毎にTwitterにPostするbotを作ったので、そのやりかたのメモメモ。

Tumblrから取得してTwitterにPostする手順

Tumblrから取得するのは普通にAPIを見ながらやってみた。
API | Tumblr

ここで困ったのが、http://hoge.tumblr.com/randomという感じでURLの最後にrandomというのを付けるとランダム記事に飛べるという機能があるんですが、
これ相当のAPIがなかったこと。

なので1度、TumblrAPIからtotal数を取得して、その値からランダム値を生成してランダムな記事のURLを再度TumblrAPIから取得しています。

Tumblrから1つの記事を取得するには以下のようなURLを指定すればよい。
typeでphotoを指定して写真を取りにいってます。

http://hoge.tumblr.com/api/read?start=0&num=1&type=photo

最近さくらインターネットを借りたので、せっかくなのでRubyで書いてみた。

ちなみにTwitterにPostするときは、定番そうなtwitter (0.7.0)を使っています。

RandomTumble - ソースコード

■ダウンロード
gist: 245238 - GitHub

使い方

RandomTumbleをnewするときにTumblrのidを渡して、random_post_twitterにTwitterのidとpasswordを渡します。

これでTumblrからランダムに1件抽出して、TwitterにPostされます。
ねっ!、簡単でしょ?

cronを設定する

さくらのコントロールパネルで、以下を設定する。

・実行コマンド

試行錯誤の結果このようになりました。

cd /home/User/code/ruby/; /usr/User/bin/ruby /home/User/code/ruby/twitter_bot.rb

[via]
Orvalで行こう!: さくらインターネット cron設定でRubyを動かす

・環境変数の設定

RUBYLIB - /home/User/lib
GEM_HOME - /home/User/lib/ruby/gem

これしとかないとrubygemsがありませんとエラーになってしまうので、忘れないように。

[via]
さくらサーバのCronでRubyを動かす時のメモ - まめ畑

・日時の設定

月 - *
日 - *
時 - */1
分 - 0

曜日すべてにチェック

初めのうちはテストとして5分ごとにして、動作確認しました。

作ったもの

tbacker (tback_bot) on Twitter

現時点で6500枚からランダムに選んでいますw
好きな人は好きになるはずっ!

■参考リンク
Net::HTTP - Rubyリファレンスマニュアル
twitter 0.7.0

jQuery Plugin - 僕のmakeClass

結構前にJohn Resig氏がJohn Resig - Simple "Class" Instantiationnewしてもしなくてもよいclassを作るmakeClassというメソッドをブログに載せていました。

ここ最近はprototype.jsを使わずにJavaScriptをコーディングする機会が増えてきたので、Class.create()の変わりになるこのmakeClassを重宝しています。

んで、これを自分が使いやすいように、改良して使っているのでそれを紹介してみます。

makeClass - before

なかなかトリッキーで面白いコードですね〜。
このnewしてもしなくても良いという部分がオモロい!

newせずに関数が呼び出された場合は、elseのほうに入って自分自身をnewしてからもう一度同じ関数を呼んでいます。

makeClass - after

では自分用にカスタマイズしたほうです。

対して変わってはいないんですが、

まずprototype.js - 1.6のClass.create()では、引数にprototypeに追加してほしいObjectを渡すことができましたので、
それと同じようにmakeClassにもpropという引数を追加。
それをreturnするfunctionのprototypeに詰めとく。

次にmakeClassをjQueryのPluginにしてしまう。
これでグローバル名前空間を汚さずに済みます。

あとbeforeのほうの以下の部分ですが、この書き方だとクラスをnewする際に引数を渡さないとargsがundefinedになってしまい、そのcalleeを見に行くのでエラーになってしまいます。

なので、ちょっと回りくどいですが、三項演算子でargsがあるかどうかで処理を分岐しています。

使ってみる

initメソッドはあればインスタンス生成時に実行され、なければ実行されません。

結構すっきりした感じで書けたと思います。
jQuery Pluginの制作で、要素ごとに何か情報を持たせようとした場合は、prototypeを使うので、そういった場面でmakeClassが役立ちます。

IE6でセキュリティ情報ダイアログがでるパターン

IE6の対応はまだまだ必要な時代ではありますが、httpsでアクセスする際にセキュリティ情報のダイアログが表示されてしまうパターンを忘れないようにメモしときます。
他にもありましたら、コメント欄で教えていただけたらと思います。

Security Information.jpg
(※画像はIETesterでのセキュリティ情報ダイアログ)

iframeにsrc属性がない場合

SSLで開いている画面にiframeタグがあり、そのsrc属性に何も指定されていない場合にIEがセキュリティ保護されているか判断できないために、発生するようです。

これは例えば、lightbox風のJavaScriptを作っているときに、IEでselectboxが前面に来てしまう問題を回避するために、iframeをoverlayレイヤーとして使用するときに発生します。
jQueryライブラリのthickboxでこの問題が発生していました。

■解決策

のようにダミーなhtmlを表示するようにすれば回避できます。

[via]
[PRB] FRAME/IFRAME を含むページを SSL により参照するとセキュリティ警告メッセージが発生する

httpsな画面でhttpなリクエスト

SSLで開いている画面にhttpでアクセスしている箇所が存在するとセキュリティダイアログが表示されてしまう。
たとえば下記のように画像ファイルをhttp経由で取得場合とかだ。

iframeにsrc属性がないと、URLがabout:blankとなり、

about:とhttps:でのスキーマ違いにより、

セキュリティ警告が出るようだ。


via: SSLなページを開くときにセキュリティ情報というダイアログが出る

■解決策

外部サーバーに直接取りにいかずに、手元のサーバーにアップして

としてアクセスすればhttpsで取得しにいくのでダイアログは表示されなくなる。

■問題点

このようにこちら側でhttpからhttpsのリクエストに変更できる場合は問題がないが、
外部サービスのscriptを読み込んでいる場合はちょっと難しい。

プロキシを作成して、サーバーサイドでscriptを読み込み、str.replaceAll("http", "https")のように書き換える必要がある。
外部サービスにhttps用のscirptが用意されているのが一番良いが、そうでない場合はダイアログが表示されてしまいますね。

jQuery.animateのcompleteでremoveするとダイアログが出る場合がある

たとえば以下のサンプルのように、divタグにcssでbackground画像を指定して、クリック時にanimateしcompleteで要素を削除するなどの場合で
SSL環境だとダイアログが出てしまう場合がある。
というか今の時点だと100%出る。(IE7では出ない)

background、backgroundImageのどちらでも再現するので、画像を指定した場合にcomplete直後だと何かブラウザ側の処理が残っていて、
その前にremoveしちゃうから出るのかな?

■解決策

とりあえずsetTimeoutで処理を後回しにすればダイアログは表示されなくなる。
かなり特殊なパターンなので、トレースが難しいがlightBox風のものを作っている人なら遭遇したことがあるかもしれない。

■追記

IE6のセキュリティダイアログは非表示にすることもできるよう。

Internet Explorer のクロスドメイン セキュリティのダイアログ ボックスが表示されないようにする - Greg Collins

ここを参考にIE6側に設定をすればいいみたいですね。

JavaScript - 右クリックを判定する(Operaもいけた)

以下ようにOperaとIEで判断が必要ですが、jQueryを使っているならOperaだけの判断でOK。

ただし、Opera の右クリックイベント検出 - Higé au laitにも記載されていますが、Opera側の設定をしてやる必要があります。
つまりデフォルトの状態だと右クリックをハンドルすることはできない。

JavaScript オプション

この画像のように、チェックを入れてあげると右クリック時のmousedownをハンドルできるようになる。

また

まだ問題がある。コンテキストメニューを表示させないで処理を実行することができない。 preventDefault() でも駄目。


via: Opera の右クリックイベント検出 - Higé au lait

というふうに書かれていたんですが、Opera10ではpreventDefaultを実行しなくともコンテキストメニューが表示されなかった。
バージョン10からそうなったのかな?

Macでローカルに手軽なSSL環境を構築する

ApacheをゴニョゴニョしてSSLな環境を構築してもよいのですが、サクッと試したいときにはXAMPPを使うと便利です。

インストールは上のリンクからMax OS X用のXAMPPをダウンロードして、dmgファイルをクリックしてアプリケーションディレクトリに放り込むだけ。

SSLモードでXAMPPを起動する

実はこの方法がapache friends - xampp for macos xに書いてある、

/Applications/XAMPP/xamppfiles/xampp startssl

をコンソールから実行しても、

Unknown command or add-on!

と表示されてないっていわれる。。。

しょうがないので、/Applications/XAMPP/xamppfiles/xamppファイルを開いて中身を眺めていたら、

"enablessl")
checkRoot

echo -n "XAMPP: " $($GETTEXT 'XAMPP: Enable SSL...')

if test -f "$lc/startssl"

こんなコードを発見!!
enablessl」じゃないかっ!

ということで、

/Applications/XAMPP/xamppfiles/xampp enablessl
/Applications/XAMPP/xamppfiles/xampp start

ってすればhttpsでアクセスできるローカル環境が作れる。

あとは、「/Applications/XAMPP/xamppfiles/htdocs/」にhtmlファイルでも置けばアクセス可能です。

windows環境で試したい場合は、apache friends - xampp for windowsからやってみてください。

さくらインターネットにRuby on Railsをインストールする方法

結構ハマりポイントがあったので、メモメモ。
ググるといろんな人のインストール方法が発見できるんですが、結構古かったりして今の環境には適さないこともあってハマった。

まずはSSHでログイン。
そしてrubyのバージョンを確認しときます。

% ruby -v
ruby 1.8.7 (2009-04-08 patchlevel 160) [i386-freebsd7]

ruby自体もインストールする手順は多々あったのですが、特にこだわりがなかったので、
標準で入っているruby 1.8.7を使うことにしました。

rubygemsをインストール

railsを入れるために、まずはrubygemsをインストールします。

% mkdir $HOME/src
% cd $HOME/src
% ftp http://rubyforge.org/frs/download.php/60718/rubygems-1.3.5.tgz

rubygemsは一応最新バージョンにしてみました。
もしこのバージョンでうまくいかない場合は他のバージョンで試したほうがよいかもしれません。

RubyForge: RubyGems: ファイルリスト

では、解凍してインストールを開始します。

% tar zxf rubygems-1.1.1.tgz
% cd rubygems-1.1.1
% ruby setup.rb --prefix=$HOME

$HOME/bin/gem18という場所にインストールされました。

次に環境変数をセットします。

$HOME/.cshrcのset pathの部分に「$HOME/lib/ruby/gem/bin」を追加し、
環境変数、RUBYLIBGEM_HOMEをセットしときます。

set path = (/sbin /bin /usr/sbin /usr/bin /usr/local/sbin /usr/local/bin $HOME/b
in $HOME/lib/ruby/gem/bin)

setenv RUBYLIB $HOME/lib
setenv GEM_HOME $HOME/lib/ruby/gem

そしたらsourceで反映させ、rehashでハッシュテーブルを更新します。

% source $HOME/.cshrc
% rehash
% gem18 -v
1.3.5

これでgemが使えるようになりました。

Ruby on Railsをインストールする

じつはここが今回くせ者で、いろんなサイトに書いてあるような、以下の感じだと最終的にrailsがうまく動きませんでした。

% gem18 install rails --include-dependencies

この方法だと2.3.4が入るのですが、railsを動作させたときに

Application error

Rails application failed to start properly"

というエラーが出て、何をどうしようがこのエラーが解消されなかったです。

[via]
さくらインターネットでRails - azlab 開発Memo

おそらくバージョンの問題だと思うのですが、結局原因は良くわかりませんでした。

なので以下のように2.2.2をインストールします。

% gem18 install rails --version=2.2.2
% rehash
% rails --v
Rails 2.2.2

Railsプロジェクトを作成する

僕は$HOMEにcodeというディレクトリを作ってその中でソースを管理しているので、ここにrailsのディレクトリを作成しました。

% cd $HOME/code/
% mkdir rails
% cd rails

そしてrailsコマンドを実行するのですが、またまたここもハマりポイントで、普通に以下のように

% rails test

としてプロジェクトを作成するんですが、railsのバージョンが2.3.2以降だと、「/test/public/dispatch.cgi」というファイルが作成されないようなのです。
まぁ今回は2.2.2を選んでインストールしているので大丈夫なんですが、初めは最新バージョンでやっていたのでハマりました。

% rails -D test

dispatch.cgiが作成されるようにするには「-D」をオプションで指定するといいみたいです。
実際にこのファイルがないと以下のようなエラーになります。

Ruby on Rails_ Welcome aboard.jpg

[via]
dispatch.cgi not found errorについて - akezoraのはてな日記

次にchmodでパーミッションを変更しときます。

% cd test
% chmod -R o+w log tmp

そして環境ファイルの設定を行います。

% vi config/environment.rb

いろんな人の書き方があったのですが、僕は以下を追記してうまくいきました。

# Be sure to restart your server when you modify this file
$LOAD_PATH.push("/home/hisasann/lib/")
$LOAD_PATH.push("/home/hisasann/lib/ruby")
ENV['GEM_HOME'] ||= '/home/hisasann/lib/ruby/gem'
ENV['RAILS_RELATIVE_URL_ROOT']="/test"

次はpublic/.htaccessです。

% vi public/.htaccess

またこのファイルがあるように手順が書かれていたのですが、僕のところにはなかったです。
なので、test/READMEの中にサンプルがあるので、そこから引っ張ってきました。

余計なコメントは削除しました。
というのも折り返しているように見えて、違う行にコメントの隅っこが移動してウマく動かなかったからです。

# General Apache options
#AddHandler fastcgi-script .fcgi
#AddHandler cgi-script .cgi
#Options +FollowSymLinks +ExecCGI

RewriteEngine On

RewriteBase /test

RewriteRule ^$ index.html [QSA]
RewriteRule ^([^.]+)$ $1.html [QSA]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)$ dispatch.cgi [QSA,L]

ErrorDocument 500 "

Application error

Rails application failed to start properly"

あと大事なのは一番最後の行に改行を入れることです。
これをしないと.htaccessがうまく読み込まれないためInternal Server Errorになって動きません!

一般公開する

$HOME/wwwが外から見える公開ディレクトリになるので、ここにシンボリックリンクを作成します。

% ln -s $HOME/code/rails/test/public $HOME/www/test

これで「Welcome aboard」画面が表示されればとりあえずうまく行きました!

sqlite3-rubyをインストールする

この時点で「About your application's environment」リンクをクリックすると、
sqliteがないとエラーになるので、最後にsqlite3をインストールします。

% gem18 install sqlite3-ruby

どうやら僕の環境では、最新バージョンがうまくインストールされませんでした。
なので、

% gem18 install sqlite3-ruby --version=1.2.4

とバージョンを指定してインストールしました。

Ruby on Rails_ Welcome aboard-1.jpg

これでエラーもなくRuby on Railsが動く状態にまで持って行けました!


あとはmysql入れて、どうやってデプロイするかを考えないと。。。

■参考リンク
がんちゃんのブログ: さくらのレンタルサーバーにRuby on Rails 2.0.2をインストールする方法
がんちゃんのブログ: さくらのレンタルサーバーにRuby on Railsをインストールする方法 その2
Ruby on Rails入門3 さくらインターネットにRuby on Railsをインストール - nyon2.net
さくらインターネットでRails - azlab 開発Memo
そんな悲しい目をしないで » Redmine
Ruby/Rubygems使い方まとめ - 俺の基地
さくらインターネットでsqlite3 - kajilog
さくらインターネットでRuby on Railsする | JAM☆ぱん

HTML5 - inputタグのrequired属性などなど

required属性

input要素に新しく追加されたrequired属性は、submitボタンが押されたタイミングでもしも値が入力されていない場合にチップを表示してくれます。
これを使うとJavaScriptで必須バリデーションを作る必要がなくなりそうで、ちょっと便利かもと思いました。
(まぁサーバーサイドのエラーチェックは必須ですけどねっ!)

チップは以下のように表示されて、ユーザーに必須であることをお知らせしています。

required

はじめsubmitボタンを押してもエラーチップが出なくてハマったのですが、どうやらname属性が必須のようです。

■対応ブラウザ
現時点ではOperaのみ、バージョンは10で試しました。

■required属性の仕様
4.10.5.2 Common input element attributes -- HTML5

placeholder

こっちはここ最近よく見る、focusがあたると文字が消えてblurすると文字が表示されるアレです。

しかもさりげなく角丸になってますw

placeholder

■対応ブラウザ
現時点ではSafariのみ、バージョンは4で試しました。

■placeholder属性の仕様
4.10.5.2 Common input element attributes -- HTML5

独自のエラーメッセージも表示できたりする(制約バリデーション API)

パスワードを確認するために、2つテキストボックスを用意することは多々ありますが、
1つ目のパスワードと2つ目のパスワードが一致していない場合はsubmitしない、なんてことも出来ちゃいます。

要素にsetCustomValidityというメソッドが追加され、ここにメッセージをセットするとエラーチップを表示してくれます。

独自メッセージ

setCustomValidityにセットしたメッセージとは別に日本語で何かメッセージが出ていますが、これ消せないのかな?

■対応ブラウザ
現時点ではOperaのみ、バージョンは10で試しました。

■制約バリデーション APIの仕様
制約 - フォーム - HTML要素 - HTML5タグリファレンス - HTML5.JP


自分の使っているブラウザでどの程度inputタグの属性がサポートされているかは、以下のサイトを閲覧すると確認できます。
HTML5 input attributes support


■参考リンク
HTML5, きちんと。

(function(){})();をもう少しスマートに書きたい

JavaScriptである程度ボリュームがある関数を書くと、変数名が被って上書きされちゃったりするので、
スコープを小さくしたいから(function(){})();で囲ってたりしたんですが、
なんかこの書き方がしっくりきてなかったので(多分最後の()が面倒なのかも?)、Pという関数を作ってみた。

$.P

使い方

一番シンプルなソース。
これで中のfunctionを呼び出してくれる。

上の感じだけだと面白くないので、実行させたいfunctionに引数を渡すこともできる。
そのときの型がfunctionの場合は実行結果を引数として渡す。

あれ?なんか余計に分かりにくくなっちゃつたかもw
う〜ん。。。

■ダウンロード
gist: 225353 - GitHub


■追記

上記パターンだと以下のようにjQueryプラグイン書くときうまくいかないな。
jQueryはfunction型だから勝手に実行されてしまう。。。

CPANがFetching with LWPの部分で止まるときの対処

cpanで何かモジュールを入れようとするときに、普通ならそんなに待ち時間がないはずなのにやたら重くなる場合がある。

cpan> install Net::Twitter
CPAN: Storable loaded ok
Going to read /Users/hoge/.cpan/Metadata
Database was generated on Sat, 10 Oct 2009 04:27:15 GMT
CPAN: LWP::UserAgent loaded ok
Fetching with LWP:
...

どうやらファイアウォールあたりの設定を強化していると、遮られてタイムアウトが連発するみたい。

Macだと「システム環境設定」の「セキュリティ」内のファイアォールタブにあるんだけど、
僕は以下のように、「必須のサービスのみ許可」にしているせいだろうか。

セキュリティ.jpg

LWPをパッシブモードで接続するようにする

LWPはパッシブモードで接続しにいくようになるので、無駄な待ち時間が無くなる


via: B-Wiki - Tips/Perl/CPANでLWPが遅い * A-tak.com

ということなので、「/User/[User Name]/.bash_profile」に対してさっそく以下を実行。

export FTP_PASSIVE=1
source .bash_profile

これで劇的にcpanモジュールのインストールが速くなった。

はい、最高です!

[via]
B-Wiki - Tips/Perl/CPANでLWPが遅い * A-tak.com

■関連リンク
パッシブモードとは 【passive mode】 - 意味/解説/説明/定義 : IT用語辞典


:追記

cpanのConfig.pmに以下を追加する必要あるのかな?(メモ)

'ftp_passive' => q[1],

VMware fusion内のWindowsにIE6、IE7、IE8を入れる方法

IE6からアップデートせずに、純正のIE6をそのまま使っていたのですが、
IE7で崩れる・IE8で動きがちょっとおかしいなど、やっぱりIE6からIE8までをローカルにインストール必要が出てきたためいろいろと試してみました。

もともとIETesterを使っていて、これで満足していたのですが、
やっぱり純正とは違う動きをしたり、「本当に純正IE6でもこうなるの?」という疑問が残る挙動したりしていたので、ここ最近は純正IE6のままにしていたのです。

まずはその苦労の流れをメモに残しておきます。


Internet Explorer Application Compatibility VPC Imageを使ってみる

初めに結論:この方法はうまくいかない

Virtual PC経由でIE6、IE7、IE8を起動出来るイメージがMicrosoftからダウンロードできるので、
まずはこれからインストールしてみました。

以下からVirtual PCをインストール

・ダウンロード
ダウンロードの詳細 : Virtual PC 2007

続いて、各IEイメージをダウンロード

・ダウンロード
Download details: IE App Compat VHD

こちらを参考に作業を進めてみました。
Windows XP の Virtual PC 環境を無料で作成する

結果的にVMware fusion上で各IE用イメージが起動できなかったです。
XPを仮想的に起動して、その中でIE6とかを起動するのですが、起動しようとした時点でVMware fusionに怒られましたw
それ以降Macを再起動しないとVMware fusion起動しなくなったので、この方法はあきらめました。。。



IE8をインストール、それ以外はスタンドアロン版を入れてみる

初めに結論:この方法はうまくいかない

IE6 と IE7 と IE8 を同じマシンで共存させる方法 - IT戦記

amachangの記事を元にまずはIE8を入れてみます。
IE6から一気にIE8にバージョンアップしてみました。

・ダウンロード
Google に最適化された Internet Explorer 8 のダウンロード

とくに問題なくインストールが完了しました。

続いて、IE7を入れます。

・ダウンロード
Internet Explorer 7 running side by side with IE6. (standalone) | TredoSoft
Download Internet Explorer 7 standalone Installer を入れました。

そして次にIE6を入れます。
Multiple IEのインストール時にIE6だけを選択してインストールしました。

・ダウンロード
Install multiple versions of IE on your PC | TredoSoft

結果的に、IE6、IE7、IE8はインストールされたのですが、2つ大きな問題がありました。

  • IE8のお気に入りを選ぶとPrint画面が表示され、お気に入りからサイトを選べない
  • IE6、IE7でサイト内にあるtextboxに値を入れられない

2個目のほうが致命的で、ログイン画面経由でどこかの画面を見たい場合にはアウトです。
おしいっ!

■参考リンク
試験管のなかのコード :: IE6, IE7, IE8 の共存方法メモ



やっぱりIETesterを使う

初めに結論:この方法で落ち着きました

今までの作業でIE8はすでに入っているのですが、スタンドアロン版のおかげでお気に入り機能が壊れているので、一旦IE8をアンインストールします。

・以下を参考にしました。
Internet Explorer 8 をアンインストールまたは削除する方法を教えてください

そして再起動。。。

またIE8のインストール。。。

そしてまたまた再起動。。。

ようやくIETesterを入れられます。

・ダウンロード
My DebugBar | IETester / Browser Compatibility Check for Internet Explorer Versions from 5.5 to 8


これで純正IE8と、IE8に互換モード用にエミュレートされているIE7とIETesterの中にあるIE6がそろいました。
IE7はIETester内にあるのを使ってもよいかもしれませんが、Cookieが使えないので、互換モードのほうがうまく動くならこっちを使いたいところです。

IE6でCookieに関するバグが出た場合にはどうしようもないですが、とりあえずこれが僕の中でベストなSetupになりそうです。



番外編 - Web SuperPreview

Microsoftが提供しているMicrosoft Expression Web SuperPreview for Windows Internet Explorerというソフトを使うと、
おそらく表示だけなんですが、IE6、IE7、IE8のデザイン違いを見ることができます。

これ使うことあるかな。。。

・ダウンロード
Download details: Expression Web SuperPreview for Internet Explorer

SinatraでちょいTwitterっぽいの書いてみた

sinatraRailsを使うほどがっつりWebアプリを作るのではなく、ちょいと試してみよう!というときにとっても助かるライブラリになります。
実際いろんなことができるので、作り込んでいけばすごいものが出来上がると思いますが、「JavaScriptを試すためにHTMLファイルを作る」と同じくらいPopにWebアプリが作れるので楽しいですね。

そんなsinatraでユーザー登録とかは特に実装していないのですが、タイムラインをAjaxで取得するみたいなものを書いてみた。
画面のデザインとか何も組み込んでいないのでシンプルですが、それっぽく試すにはちょうどいいですね。

sinatraのインストール

まずはsinatraのインストールです。

sudo gem install sinatra

これだけでsinatraの環境が整うのが面白い。

あとは

hello.rbとして保存して、以下を実行するだけ。

ruby hoge.rb

これで、http://localhost:4567/にアクセスすると、Hello World!!が表示されます。

今回使うライブラリのインストール

今回使用するライブラリをインストールしときます。

sudo gem install json
sudo gem install haml
sudo gem install sequel

DBはSqliteを使いました。Mac OS Xにはじめから入っているので楽チンですね。

twitter.rb

今回SequelというDB用ライブラリを使ってみたのですが、これは使いやすいですね。
たとえばもし該当のテーブルがなかった場合は、自動的に作ってくれる(create_tableメソッド)ので、Sqliteクライアントを使って自分でcreate tableをしなくてよいので楽です。

index.haml

テンプレートライブラリとしてhamlを使ってみたのですが、なかなかこれも面白い。
以下を参考に書いてみました。

ウノウラボ Unoh Labs: 5分で分かるHaml

@Timelinesや@UsersにDBから取得したタイムラインたちが入っているので、これをeachでイテレートしています。
中身はハッシュなので、timeline.messageという感じで取得が可能です。

ダウンロード

一応githubにアップしときました。

gist: 210639 - GitHub
gist: 210640 - GitHub

■関連リンク
Sinatra: README (Japanese)
ウノウラボ Unoh Labs: Sinatra気に入った
Ruby Freaks Lounge:第9回 SinatraとSequel・Hamlで掲示板アプリを作る|gihyo.jp ... 技術評論社
Rubyの軽量Webフレームワーク「Sinatra」がステキ - 医者を志す妻を応援する夫の日記

iframe内のDomContentLoadedを監視する方法

あまりないシチュエーションですが、iframeを動的に生成して作った場合にreadyを待ってiframe内の関数やら要素やらを参照する場合はjQuery.isReadyを監視すればよい。

この方法で、window.openしたウィンドウのDomContentLoadedのタイミングも取得できる。
jQueryテストツールのQUnitなんかが同じような方法を使っている。

親画面のHTML

iframe内のHTML


初めて知ったのですが、

でiframe内のhtml全体が取得できるので、ここからfindできるみたい。

だからいちいち

ってしなくても取得が可能。

■関連記事
JavaScriptで単体テストをするならQUnitはいかが?

■関連リンク
iframe 関連処理まとめ - Cyokodog::Diary
iframe内のコンテンツを親からスクロールさせる :: 5509
JavaScript インラインフレーム(iframe)関連 - とみぞーノート

ニコニコ動画検索ページを「再生が多い順」にするグリモン

ここ最近全然グリモン書いていなかったのですが、ニコニコ動画の検索ページのソート順プルダウンを毎回「再生が多い順」するという作業が面倒になってきたので書いた。

XPath使っちゃったので、HTMLの構造が変わったらアウトですが、今のうちは大丈夫そうだ。

ダウンロード

NicoSearchMostPlayback for Greasemonkey

NoTechnoNoLifeのタイトルFlashの解説

NoTechnoNoLifeのタイトルFlashの解説

自分のブログNoTechnoNoLifeのタイトルFlashを「どうやって作っているの?」とコメントで質問されましたので、たいしたFlashではないのですが、ざっくり紹介してみようと思います。

ブログにアニメーションするFlashを導入する場合、一番気になるのがHTMLのレンダリングに邪魔されてFlashのアニメーションがカクカクしちゃうということですが、
これに関してはdelay(遅延)を使ってある程度防ぐ方法にしています。
とくに動画を紹介しているサイトだと結構重くなるので、そうゆうときがこれまた難しいですね。

JavaScriptからDomContentLoadedのタイミングを受け取って、そのときにアニメーションを開始するなんて方法も使えそうですが、ExtarnalInterfaceを使いたくなかったので、こうゆう方法は使っていないです。

サンプルページ

まずはサンプルとなるページを用意したので、こちらをご覧ください。
NoTechnoNoLife/test.html

初めにタイトルとなるNoTechnoNoLifeの画像を表示しておいて、2秒ほど遅延させます。
その後に足やフラワーがアニメーションし始めます。

レイヤーの説明

これを表現するのに、今回は3枚のレイヤーを作っています。

タイトル画像を持つBaseLayer 足の部分を持つLegLayer そして最後に上から降りてくるflowerLayer

このFlashをクリックすると、自分の画面をリロードするのですが、これはflowerLayerにリンク機能を付けて実現しています。
なので、flowerLayerが降りて来ない限りクリックしても無反応になっています。(これはこれで問題かな。。。)

リンク機能もいろいろあって、JavaScriptのlocation.hrefを呼び出すとかあるのですが、微妙にクロスブラウザの処理が必要なので、

こんな風にnavigateToURLメソッドを使うようにしています。
これだとどのブラウザでクリックしても同じ挙動でした。

そしてこれらを順番にSpriteにaddChildしていき、それっぽくdelayをかけてアニメーションさせています。

使っているライブラリ

アニメーションの部分ではTweenerを使っていて、モザイクの機能も足したかったので、@24Log » Blog Archive » Tweenerでモザイク処理できるようにしてみたからモザイク用のライブラリを拝借して使っています。

いや〜助かります!

ソースコード

ブログに貼付けるにはちょっとコード量が多かったので、以下に置いておきます。

gist: 204756 - GitHub

まとめ

完全に自分用に作ったActionScriptなので、とっても恥ずかしいのですが、誰かのWeb制作の手助けになれば幸いです。

あと気分で画像やアニメーションを変えることがあると思いますので。。

JavaScript - HelloWorld

HelloWorld.png

前回jQuery.animateを順番に実行するaddCommand作りましたで紹介したaddCommand - jQuery Pluginを使ってアニメーション「HelloWorld」を書いてみました。

少ないコードでストーリーっぽいアニメーションを描くことができるので、この手のscriptを書くのに適しています。
まだまだ課題はあるんですがね。。。

アニメーションする要素の量が多いので、SafariかChromeで見た方がスムーズに動くと思います。

画像を使ったHelloWorld

・サンプル
addCommand - HelloWorld

・コード
gist: 200472 - GitHub

HTMLテキストを使ったHelloWorld

CSS3のText-Shadowを使っているので、Safari 3+, Opera 9.5, Firefox3.+で見てくださいね。

・サンプル
addCommand - HelloWorld2

・コード
gist: 200473 - GitHub

コードの解説

このコードは「画像を使ったHelloWorld」のJavaScript部分になるのですが、初めのfor文で各画像を画面外に配置して、座標をjQuery.dataに格納しておきます。

そして画像の個数分addCommandメソッドを使ってアニメーションをセットしていきます。
途中、「100 * index」としてdelayを掛けて遅延させてます。

大体これぐらいのコードを書けば、それっぽくアニメーションさせることが可能です。

以上、HelloWorldでした!

■関連リンク
addCommand - jQuery Plugin

■関連記事
ActionScript3 - HelloWorld
CSS3のText-Shadowで文字にEffectをかけてみる

jQuery.animateを順番に実行するaddCommand作りました - jQuery Plugin

jQueryで1つのアニメーションが終わったあとに、違うアニメーションを実行させたい場合は、callbackを使う必要があります。

これだとちょっとネストしちゃうし、なんとなく使い勝手が悪いので、セットした順番にアニメーション処理を実行するFlashのライブラリProgressionのaddCommandっぽいものを作ってみました。

何かJavaScriptでアニメーション作品を作ろうとすると必ずこの「1つずつアニメーション問題」が発生するので、この手の作品作りで何かの役にたてば幸いです!

addCommand - jQuery Plugin

使い方

Prop($.css)とDoTweener($.animate)というクラスを渡したり、functionを渡したり、さらに一気にアニメーションさせるように配列にDoTweenerを詰めて渡したり出来ます。

詳細

細かい使い方は以下のサイトに用意しましたので、参考までに。

addCommand - jQuery Plugin

サンプル動画

あと1個前のエントリーでJavaScriptでスクロールバーを波打たせる - Scrollbars Experimentを紹介しましたが、それっぽいことをaddCommandを使って作ってみました。

addCommand - Screencast from hisasann on Vimeo.

サンプル動画のソースコード

gist: 190118 - GitHub


またこの他のライブラリや作品はhisasann.comに掲載していますので、是非ご覧ください。

JavaScriptでスクロールバーを波打たせる - Scrollbars Experiment

まだどやって実現しているか見ていないのですが、divタグが何個も並んでいて、onscrollで隣接するスクロールバーの高さから計算して波打たせてるのかな。

Webkit系のエンジンで見るといい感じになりそうです。

Chrome Experiments - Detail - Wavy Scrollbars

[via]
House dust

CSS3のText-Shadowで文字にEffectをかけてみる

Pure CSS Letterpress Effect.jpg

Create a Letterpress Effect with CSS Text-Shadowの記事を見て触発された。

text-shadowというCSS3のプロパティを使うと上の画像のように、テキストにエフェクトをかけることが可能になる。

たとえば以下の感じ。

指定している値については以下を参照。

X軸方向への距離
左右のぼかし距離、マイナス値だと左、プラス値だと右。
Y軸方向への距離
上下のぼかし距離、マイナス値だと上、プラス値だと下。
ぼかし距離
ここを大きくするとぼかしの範囲が大きくなる。
ぼかしの色、この部分は最後に書いても最初に書いても同じように動作する。
つまりtext-shadow: #555 2px 5px 5px;でもよい。

サンプルコード

テストページ作ってみた。
ファイアーの感じとかも出せるので、これは楽しいですね!
CSS3 text-shadow Effect

■関連リンク
text-shadow - CSS Dencitie

CRASHCLOCK - SRC

21_21 DESIGN SIGHT-「骨」展 Bonesで発表されたSCRtha ltd.)制作のFlash作品。

トラス構造が物理演算で崩壊していく感じがステキすぎる!

SCR | CRASHCLOCK by thaここからスクリーンセーバーをダウンロードできるんですが、パソコンの性能が結構よくないと本来の動きは体感できないかもしれませんね。

中村勇吾氏、ハンパねぇな〜w

HTML5とCSS3を使ったすばらしいDEMO「死にたい」



WebKit Nightly Buildsを使った面白いデモがありました。

以下の記事で詳細が見れるのですが、デモの映像を見ているだけでHTML5とCSS3の可能性にわくわくしちゃいます。
とは言ってもまだまだWebkitのNightlyバージョンでしかこの動きは厳しいようで、今後各ブラウザがHTML5とCSS3に対応していくとしてもまだまだ厳しいんでしょうね。

HTML5 と CSS3 で 死にたい


サンプルページは\(^o^)/ - HTML5 CSS3 DEMOっ アニメーション - \(^o^)/になりますが、


サンプルページは高負荷です。パソコンの性能によってはカクカクしたり、最悪ブラウザがフリーズする可能性があります。

via: HTML5 と CSS3 で 死にたい

とのことですので、なるべくWebkitのNightlyで見るようにしましょう。

僕も何か作ってみたくなりましたw

いろんな言語のクロージャ

以前にJavaScriptのクロージャを無名関数、クロージャ、そしてレキシカルスコープへでまとめたのですが、今回は他のスクリプト系言語のクロージャを取り上げてみたいと思います。

Rubyのクロージャ

Rubyで関数と呼ばれるものは必ずクラスに所属しています。
トップレベルな空間にメソッドを定義するとObjectクラスに所属するメソッドになるようです。

そしてRubyのクロージャは実際には関数オブジェクトではなく、Procというクラスのインスタンスを返すようです。
Proc.newにはブロックを渡しこれをオブジェクト化したものを返すとクロージャが出来上がるというのが大体のイメージになります。

小難しいので以下のコードを見てください。

まず外側にある関数get_closureにはローカル変数としてcountがあります。
そしてreturnでProcインスタンス、つまりクロージャを返すようにしています。

このクロージャを取得すると呼び出すたびにブロックに渡された引数をcountに加算していきます。
JavaScriptのようにreturn function(){}のように無名関数を渡すのとちょっと違い、ブロックオブジェクトというところが難しいところですね。

そしてProc.new意外にもクロージャを作れるものとしてlambdaprocがあります。
書き方は以下の感じ。

※補足
Proc.newとlambdaの違いは、
lambdaのほうはブロックに渡された引数の数とcallメソッドが呼ばれたときの引数の数をチェックするが、Procのほうにはnilが入るみたいです。

[via]
Rubyのblock、Proc、lambdaを理解する - 医者を志す妻を応援する夫の日記

■参考リンク
Rubyの「クロージャ」再考 - バリケンのRuby日記 - Rubyist
まつもと直伝 プログラミングのオキテ 第5回(3) - まつもと直伝 プログラミングのオキテ:ITpro

Perlのクロージャ

まずブロックスコープを作成し、その中で$count変数とクロージャとなる$closure変数に関数を代入しています。
こうすることで$count変数は$closure関数が参照している間解放されずにスコープに存在し続けます。

Rubyの場合はブロックをreturnしていましたが、Perlではブロックで囲った中で関数を代入するという方法でできるんですね。
でもこの方法以外にもPerlだからいろんなトリックがありそうです。。。

■参考リンク
Perl5編 第28章 クロージャ
クロージャの定義 - Perl入門〜サンプルコードによるPerl入門〜

Pythonのクロージャ

Pythonの場合は先ほどRubyで出てきたlambdaを使うかローカル関数を定義してそれを返すかの2通りのようです。

ただPythonでクロージャを作る場合にはちょっとだけ注意する点があります。

僕はPythonのバージョン2.5.1を使っているのですが、このバージョンでは内側にある関数内で外側にある関数の変数に値を代入できません。
Pythonでは代入とはローカル変数に対して実行されるので、内側の関数内でcount += argとすると、

UnboundLocalError: local variable 'count' referenced before assignment

となり未初期化変数への加算となりエラーになってしまいます。
これを防ぐのにリストに入れるというのがあるようです。(トリッキーだな〜w)

Python3からはnonlocalとローカル変数ではないという情報を変数にもたせることができるので、
nonlocal count += argと書けるみたいです。

■関連リンク
Python 3.0 Hacks:第1回 nonlocalでクロージャが便利に|gihyo.jp ... 技術評論社
お気楽 Python プログラミング入門:第3回再帰定義と高階関数
pythonでクロージャ
Pythonでのクロージャは? - def __mopemope__(self, *args, **kwargs):

JavaScriptのクロージャ

普段使い慣れているだけあって、一番理解しやすいのがJavaScriptのクロージャです。
関数オブジェクトをreturnできるので、クロージャ=関数という感覚が掴めるので馴染みやすいクロージャですね。

無名関数を即時実行してclosure変数にはreturnされた関数オブジェクトが格納されています。
これでclosure関数を呼び出すとcount変数がレキシカルスコープになり、引数の値が加算されていく感じです。

ActionScript3のクロージャ

ActionScriptにはFunctionという型があるので、無名関数を作ってreturnするだけでクロージャが出来上がる。
JavaScriptとほぼ一緒ですね。

Javaのクロージャ

Java7でクロージャが入る入らないという話が以前盛り上がりましたが、あれってどうなったんだろう。。。

現時点でJavaにクロージャはありませんが、それっぽいものは存在します。
無名関数ではなく無名クラスです。

以下がクロージャ的無名クラスを返すクラスである。
このクラスのgetCounterメソッドを実行すると、return new Counter()と
何かクラスのようなものをnewしている。

本来ならreturn new (){}としたいところなのだが、受け取り側でどのような型で取得すればよいのが分からない。
静的言語ゆえな面倒くささはあるのだが、interfaceかClassを事前に定義しておき、
それを指定してnewする感じで使うのが一般的にようです。
今回はinterfaceが上位型の無名クラスなので上位クラスはjava.lang.Objectになる。

こっちは無名クラスを使うほう。

クロージャ(無名クラス)を取得しているgetCounterの型はClosureClass.Counterになるので
変数にもこの型を指定している。

まとめ

いろんな言語のクロージャを取り上げてみたが、プログラム言語ごとに仕様は違うし分かりやすいものもあれば
分かりにくいものも存在する。
Java7のクロージャの解説記事Java 7のクロージャ(BGGA版)のプロトタイプを試してみた(2)を見てみたのですが、さっぱり分からなかった。

ってかクロージャなのか?w

今回解説した内容意外でもさまざまな方法でクロージャを作成する方法があるかもしれません。
そうゆうハックを探すのもプログラム言語を理解するためには重要ですね。

■関連記事
クロージャのスコープは関数オブジェクト単位だよ
JavaScriptでちょっと面白いコード - 式クロージャ

JavaScriptライブラリ「Grow」のDomContentLoaded判定方法

JavaScriptライブラリGlowのDomContentLoaded判定部分をメモメモ。 jQueryとほぼ同じ感じだけど、glow.env.webkit < 525.13の判定はこのバージョン未満だとDomContentLoadedがないのかな? あと というonloadの詰め替えラッパーの記述がなつかしい。

Rubyでファイル名を使いたいモジュール名と同じにすると動かなくなる

ちょいハマってしまったのだが、何か試したいモジュールをgemとかでダウンロードしてきて、よしさっそく試してみるかとrubyファイルを作成したが実行してみるといっこうにエラーが消えない現象がある。

以下がどんぴしゃな内容なのだが、

モジュールを利用したRubyスクリプトが突然Name Errorになる - お題目うぉっち

ようはテスト用プログラムのファイル名をダウンロードしてきたモジュール名と同じにすると動かないということみたい。


Running

この現象に気がついたのが、Anemone - Ruby Web-Spider Frameworkというサイトをクロールしてリンクを取得してくるモジュールを試す際に同じ名前のanemone.rbというファイルを作成したのが原因。

もしもどうしてもanemone_test.rbとか作成したくない〜という場合は、ファイル名はanemone.rbにしておいて、requireで読み込む先を以下のようにすると動くようになる。

SafariのWebインスペクタはFirebugっぽくウィンドウに統合できる

知らなかった〜。
ゆえにあんまりSafariを開発用ブラウザにしてなかったw

以下のようにWebインスペクタの左下のボタンを押すと。


こんな感じにSafariのウィンドウに統合できるみたい。

でもFirebugの調査みたいに、マウスをもって行った箇所を表示するって機能はまだないのかな?
これがないといちいちhtmlタグから順番に降りていかないといけないから面倒・・・

RhinoでJavascriptの継続を使ってみる

継続と言うとSchemeが有名ですが、Rhinoのドキュメントを読んでいたら「Rhino 1.6R1」から継続が存在してたみたいだったのでとりあえず試してみた。
Rhino 1.6R1 変更ログ

継続とは?

継続と聞くとちょっと小難しいので、まずは軽く説明してみます。
継続とは「ある時点での状態」を変数に格納しておき、そのポイントに後から戻るということが可能になる概念である。

・・・

まったくもって小難しいのでとりあえず以下のSchemeのコードを見ていただきたい。

継続サンプル - Scheme

結果

こぶた
たぬき
きつね
ねこ

[via]
Schemeを作ろう 第3回

このコードではdisplayで文字を出力しているのだが、途中のcall/ccという部分が継続オブジェクトを生成している部分になる。
この継続オブジェクトをx変数にセットしているので、もし後でx変数に入っている継続オブジェクトを実行するとさらに

きつね
ねこ

と文字列が出力される。
このようにあるポイントを変数に記憶させておき後から呼び出せるのが継続になるのだ。

そしてそのときのスコープ内の値も保持されているのでクロージャっぽいですね。
ってかクロージャも継続と言ってもいいのかな?

Rhinoをインストールする

一応Rhinoを使ってJavaScriptの継続を試すのでのインストールを書いておきます。参考までに。
あとボクの環境がMacなのでWindowsの方は適宜読み替えていただきたい。

まずは以下からダウンロードします。
Rhino のダウンロード

そしてRhino Shellが使えるように、環境変数を設定しましょう!

ホールディレクトリにある.bash_profileファイルに以下を追記します。
(CLASSPATHに入れるパスはご自分の環境に合わせてくださいね。)

export CLASSPATH=/code/java/rhino1_7R1/js.jar
alias rhino="java org.mozilla.javascript.tools.shell.Main"

.bash_profileへの追記などは以下を参考にしてみてください。
Mac OS Xで環境変数にPATHを追加する方法

設定が終わったら、ターミナルから

$ rhino

と打つとそのままJavaScriptがirb形式でコードを入力できます。
rhinoから抜けたい場合は「quit()」と入力してください。

継続オブジェクトContinuationを使ってみよう

Rhinoで継続を使う場合は、Continuationというクラスをnewすることから始まります。
Continuationクラスをnewして変数に格納すれば、そこが継続として後から戻るポイントになります。

では実際に使ってみましょう!

このコードを保存してrhinoコマンドで実行します。

$ rhino -opt -1 -f coroutine.js

-opt -1は継続を使う場合に必要で、-fはファイルから実行するという意味になります。
Rhino Shell - MDC

先ほどのSchemeのコードに近い感じですが、showMessage関数を呼ぶとprint関数で順番に文字を出力していきますが、
途中にあるcall_cc関数内でContinuationクラスをnewして継続オブジェクトを返しています。
(ここでreturnされるオブジェクトはfunction型になります。)

そしてshowMessage関数の呼び出しの後に継続オブジェクトを関数として呼び出しています。
ただし継続オブジェクトが実行した後はc変数に入っている継続オブジェクトはundefinedになってしまうので、instanceofで継続オブジェクトかどうか判断しています。
これについては順番に説明して理解してみましょう!

以下にshowMessage関数を呼び出したところから処理の流れを記載してみました。

showMessage関数の呼び出し

文字列の出力(hoge1)

Continuationオブジェクトの生成

文字列の出力(hoge2、hoge3)

instanceofで確認→OK

継続関数オブジェクトの実行

文字列の出力(hoge2、hoge3)

instanceofで確認→NG

よって2回目の継続関数オブジェクトは実行されない

ちょっとややこしいですが、c()で継続関数を実行すると継続ポイントに戻って再度コードを実行していきますが、
再びc()の部分まで実行しようとしているのでそれをinstanceofで阻止している感じです。

また継続オブジェクトには引数を渡すこともできます。
「c("foo");」という感じで呼び出すと、「c = "foo"」と同じになり継続オブジェクトに渡す引数で処理を分岐したりもできます。

JavaScript1.7のyieldに似てる

一見yieldを使うと同じような雰囲気は出てるんですが、継続と少し違うのはyieldはポイントポイントで完全に処理が止まって待っててくれるのですが、
継続は処理をすべて1度実行しちゃいます。

継続とyieldの出力結果を見るとよく理解できると思います。

継続の場合の出力結果

hoge1
hoge2
hoge3
hoge4 ←ここが継続ポイント
hoge5

yieldの場合の出力結果

hoge1
hoge2
hoge3

まとめ

継続をどのようにうまく使うかなど、まだ全然理解できていないのでこれから少し掘り下げて勉強してみたいと思います。
(それならScheme勉強したほうが良さそうですねw)

あとGemmaさんの記事で、サーバーサイドJavaScript(Rhino)の継続でCoroutineを書いてみた - Gemmaの日記
というのがすごく参考になります、2つの関数を交互に実行する協調的マルチタスクな処理実装されています。
すごいっす。

■参考リンク
RhinoWithContinuations - Cocoon Wiki

画像をめくるjQuery Plugin - jStack作りました

画像をめくるjQuery Plugin - jStack作りました

Mootools版のmooStackからインスパイアされてjQuery版を作ってみました。

ただ画像をめくるだけだとつまらないので、トランプのようにシャッフルする機能を入れてみました。
ちょっと面白い動きをするのでなかなか気に入ってます。
遊んでみてください〜!

デモ、詳細は以下からどうぞ。
jStack.js - jQuery Plugin

■他に作ったもの。
画像がグルグル回るjQuery Plugin - jMerrygoround作りました

Macに発音させるsayコマンドでDaftPunkは厳しい

MacWiki - コマンド/say
Macに標準でインストールされているsayコマンドは、引数に与えた文字を読み上げてくれるコマンドです。
この時点でちょっと面白いのですが、さらに声の種類も豊富にあるのでいずれかを選んで発音させることができます。

実際のVoiceは以下のようになっており、結構種類がある。

$ ls /System/Library/Speech/Voices/

Agnes.SpeechVoice
Albert.SpeechVoice
Alex.SpeechVoice
BadNews.SpeechVoice
Bahh.SpeechVoice
Bells.SpeechVoice
Boing.SpeechVoice
Bruce.SpeechVoice
Bubbles.SpeechVoice
Cellos.SpeechVoice
Deranged.SpeechVoice
Fred.SpeechVoice
GoodNews.SpeechVoice
Hysterical.SpeechVoice
Junior.SpeechVoice
Kathy.SpeechVoice
Organ.SpeechVoice
Princess.SpeechVoice
Ralph.SpeechVoice
Trinoids.SpeechVoice
Vicki.SpeechVoice
Victoria.SpeechVoice
Whisper.SpeechVoice
Zarvox.SpeechVoice

この中でBadNewsとGoodNewsが使えなかったのですが、原因不明・・・

Voiceを選ぶときには-vオプションを指定する

say -v Boing San of a bitch

すべてのVoiceで発音させるシェルプログラム

すべてのVoiceを列挙して順番に発音させていきます。

Daft Punkっぽくやってみたかったけどダメだった

THE DAFT PUNK'S CONSOLE by NAJLE.comこれを見てsayコマンドでできるかな〜と簡単に考えていましたがやっぱりダメだった。
でもちょっとそれっぽくはなったかも。

全パターンを聞いてみて、「harder better faster stronger」の声に似ているのはTrinoidsでした。

これは近いんだけどキーを上げれないから厳しいな。
でも気合い入れればそれっぽくなるかも!
あとdo itのところが速過ぎるw

■関連リンク
シェルの変数に慣れる
【 文字列を置換する「sed」 】:ITpro
シェルスクリプト入門
・Macの読み上げアプリアップル - ダウンロード - ユーティリティ - iSpeech

Daft Bodies - Harder, Better, Faster, Stronger

この映像が本来のPVな気がしてきたw

ActionScript3 - HelloWorld

にとよんさんが作られたHelloWorldFlashをForkしてみた。

文字のラインにCircleを描く

forked from: Hello World!!! - wonderfl build flash online

元々のHello World!!! | wonderfl build flash onlineではFlash内をCircleで埋め尽くしていますが、ボクのほうは文字のラインにだけCircleを描くようにしています。

あとfiltersを使ってぼかして、BlendMode.ADDでキラキラさせてます。

文字のラインにアルファベットを描く

forked from: Hello World!!! - wonderfl build flash online

アルファベットにalphaを指定したいんですが、うまくいかなくてTextFieldにalphaをつける | (SCRATCHBRAIN.BLOG v2)を参考にやってみたのですが激重になってしまったので、画面の外からアルファベットを出現するようにしています。
こっちはいまいち文字が読めない感が否めない・・・

プログラムコード(Circleのほう)

PerlのMVCフレームワークCatalystをインストールしてみた

PerlのWAFを使ったことがなかったので、インストールしてみたのですがいやはや苦労しちゃいましたのでメモメモ。

インストール環境

OS
MacOS X Leopard
Perl
5.8.8

CPANからのインストール

ネットでCatalystのインストール方法を見ていると、いろんな人がいろんな方法でやっていて正直難しかったです。
どうやら以下の2つのモジュールを入れれば良さそうだと分かっても、CPANがアクセスするftpサーバーの都合でダウンロードできなかったりと意外と面倒でした。

  • Catalyst::Runtime
  • Catalyst::Devel


それで最終的に行きついたサイトが以下。
perl:catalyst [kazusa wiki]

こちらではcat-installというファイルをダウンロードし、

perl cat-install

を実行する。
これでCatalyst::Runtimeモジュールがインストールされます。

そして次に

sudo cpan Catalyst::Devel

を実行して、もう一つのモジュールをインストールします。

ただ、

Your terminal expects ISO-8859-1 (yes/no)? [yes] no

というのを聞かれなかったんだけど、途中に出てきてたのかな?
見当たりませんでしたw

CPANの接続先ftpでエラー

Not Connectのエラーがコンソールに出ていて、何回かやるとうまくいきそうなんだけど、ダメみたいでハマった。
調べてみたらCPANの接続先を追加するとうまくいくとなっていたので以下を参考に追加してみました。
LunaTear: CPANのサーバー追加

cpan
cpan> o conf urllist push ftp://ftp.u-aizu.ac.jp/pub/CPAN
cpan> o conf urllist push ftp://ftp.dti.ad.jp/pub/lang/CPAN/

そして一応追加されているか確認。

cpan> o conf urllist

大丈夫だったら

cpan> o conf commit

これで変更が反映されます。
commitしないといくらやっても接続先サーバーが追加されないので注意が必要です。

雛形を作ってみる

Ruby on Railsのようにザクッとテンプレートを作ってくれるので、ここがCatalystの魅力なんでしょうね。
コンソールで、

catalyst.pl HelloWorld

これでモデル、コントロール、ビューあたりが自動生成されるようです。

そしたらHelloWorldフォルダの中にあるスクリプトを実行してスタンドアロンな簡易サーバーを起動してみます。

cd HelloWorld
./script/helloworld_server.pl

これを実行するとコンソールにURLが表示されるので、後はブラウザでアクセスするだけです。

HelloWorld on Catalyst 5.80002

まとめ

Javaに慣れていると必要なライブラリはlibの中に入れとけば動くという感覚なんですが、こうゆう風にCPANから必要モジュールをインストールし、それらが「/Library/Perl/5.8.8」に勝手に展開されて後は呼び出すだけというのがまだちょっと慣れない。
どちらかと言えばプロジェクト単位にライブラリを配置したいという感じがします。

Movable Typeなんかがその方法を使っていて、必要なCPANモジュールはextlibというフォルダに格納されています。
なのでプログラムコードの中でそこを見に行くように、

なんてことをしないといけないのですが、どちらかというとボクはこっちより。
このブログのレンタルサーバーはロリポップを使っているのですが、telnetもsshも使えないのでCPANからインストールという方法が使えなそうです。
だからデプロイもftpになるのかな?めっ、面倒だ・・・w

最もシンプルにJavaのAOPを書いてみる→そしてJavaScriptへ

SpringSeasar2などのFrameworkを使っているとDIやAOPを簡単に実現できますが、このAOPを自前で手軽に書くにはどうやるのかな〜と思って調べてみた。
AOPとは[ThinkIT] 第5回:AOPとは何か (1/4)あたりを読むと分かりますが、ある処理を実行する前や後に追加で処理を入れることをいい、しかも実装クラスには手をつけずに外から処理を追加するように見せるのが特徴です。

ではシンプルにAOPを実現するコードを書いてみます。
今回はServiceというInterfaceを実装したServiceImplに文字を出力する処理だけを記述し、その前後にロギングの処理をAOPで織り込んでおきます。

Main.java

まずはメインとなる実行クラスを作ります。
このクラスで重要なのはProxy.newProxyInstanceというメソッドを使ってプロキシクラスを取得していることです。
たとえばServiceImplを普通にnewしてしまうと、純粋に文字を出力する処理しか存在しませんがこれではAOPを入れる隙間がありません。
なのでプロキシクラスを経由してServiceImplの処理を呼んでもらうようにします。

それがProxyというクラスの役目になります。

Proxy.newProxyInstanceメソッドの引数は

ClassLoader
プロキシクラスを定義するクラスローダ
Class<?>[]
プロキシクラスが実装するインタフェースのリスト
InvocationHandler
メソッド呼び出しのディスパッチ先の呼び出しハンドラ

になります。
第3引数に渡すInvocationHandlerに渡すクラスが実際のAOPとして折り込みたい処理を実装したクラスになります。
詳細は後で紹介します。

■参考リンク
Proxy (Java 2 Platform SE 5.0)

Service.java

普通にインターフェースです。

ServiceImpl.java

文字出力処理を実装しているクラスになります。
文字を出力し、returnとして出力した文字を返しています。

Intercepter.java

プロキシを作成するためにまずはInvocationHandlerインターフェースをimplementする必要があります。
そしてService.print()が呼び出されるとこのクラスのinvokeがディスパッチされます。

invokeメソッドの引数は

Object proxy
プロキシクラスの参照
Method
呼び出されたメソッドのMethodオブジェクト
Object[]
呼び出されたメソッドの引数配列

になっています。
ひとつ気をつけたいのはmethod.invokeを呼び出すさいの第1引数はproxy変数ではないことです。
proxy変数にはプロキシクラスの参照が入っているので、もしproxy変数をmethod.invokeに渡してしまうと無限にループしてしまいます。
なのでこのクラスではコンストラクタに実装クラスを渡すようにしています。
そして実装クラスをオブジェクトとしてmethodを呼び出します。

■参考リンク
InvocationHandler


これらを実装してMain.javaを実行するとprintの前と後にログ処理が追加され文字がコンソールに出力されます。
ちょっぴり面倒ですが、Intercepterクラスをしっかり作ればもっといろんあ織り込み処理が作れそうですね。

JavaScriptでAOPを実現してみる

では次にJavaScriptで↑で説明したようなAOPを作ってみたいと思います。
名前を一緒にしたほうが分かりやすいのでProxy.newProxyInstanceという関数を作り、この関数からプロキシオブジェクトを取得します。
実際にはオブジェクトを作り直しているだけですが、JavaのProxyクラスも同じようなことをやっているのでそこまで違いはないと思います。

コードは以下のとおり。

まとめ

JavaScriptでAOPを使うことは今のところないとは思いますが、いずれクライアントサイド・ストレージを使ってブラウザ側のDBを使うときにトランザクションをAOPを使って織り込みたいといった要望がでてきたときに便利かもしれません。
trycatchで囲ったりしてコネクション繋いだりトランザクション貼ったりするのはコード量も増えますし、結構面倒だったりもしますしね。

jQueryでツールチップを表示するシンプルなコード

そこまでシンプルでもないかもしれませんが、一応書いてみた。

構成としては、

  1. チップ用のdivタグを生成する
  2. チップを表示する対象となるSelectorにマウスイベントをセットする

これだけ。


■プログラムコード
一応jQueryPluginとして書いてみました。

このjsを読み込んだら、後は以下のように呼び出すだけ。

何度も呼ぶのがちょっと・・・
もうちょいキレイにして機能追加してPlugin化するのもありかな。

追記:
一応デモを用意してみた。
jAltTip.js - jQuery Plugin

Papervision3D - BitmapLayerEffectを試してみた

Mozilla Firefox

ActionScriptで3D空間 - Papervision3Dをためしてみたに引き続きPapervision3Dで遊んでみた。

Papervision3Dが持つBitmapLayerEffectクラスでどうやらエフェクト効果を付けられるようなので、試してみました。
それと奥のほうからズームするようにプログラムを少し修正。

ちょっぴり3Dっぽくなってきました。

Continue reading

ActionScriptで3D空間 - Papervision3Dをためしてみた

ActionScriptで3D空間 - Papervision3Dをためしてみた

Papervision3DはFlashを使って3D空間を簡単に作成できるようにしたActionScriptライブラリです。
Versionが1.Xから2.Xに変わって、かなり仕様が変わったようでネットに転がっているサンプルが結構動かなくて四苦八苦してしまったのでメモメモ。

ぶっちゃけ簡単にと言いましたがそれでもかなり敷居が高いと思います。
でも100行ちょいで3Dを描くことができるので、使い始めるとあっという間に時間がすぎてくほど面白いライブラリ。

ではさっそく使ってみましょう。

Continue reading

いろんな言語のSetter・Getterを比較してみた

プロパティ(属性)を持つクラスを使う場面は開発を行って行くと多々ありますが、各言語によって書き方はまちまちです。

とは言っても目指すところは同じだと思いますので、以下に何個か載せてみました。

JavaScriptのSetter・Getter

IE6、7で実装されていないため、今まで開発では全く使ったことがないですが、使い始めると便利そうですね。

現時点では以下の2パターンでgettter、setterを定義できる。

・Firefox独自実装、その後Safari・Operaも実装

  • __defineSetter__
  • __defineGetter__


・ECMAScript3.1実装

  • get getter()
  • set setter(value)


以下のコードはFirefox、Safari、Operaで動作確認済。

またIE8に実装されたObject.definePropertyメソッドというのがあるみたいなんですが、手元にIE8がないため確認できてないです。
詳細は以下に記述されてます。
IE8 の DOM のプロトタイプと Getter/Setter API はどうなるか - IT戦記
次の JavaScript の仕様はこうなる! ECMAScript 3.0 から 3.1 への変更点まとめ - IT戦記

ActionScript3のSetter・Getter

なんとなくこっちのほうが使う機会が多そう。


詳しい内容は以下からどうぞ。
【AS3入門】getterとsetter - 独学ActionScript

PerlのSetter・Getter

Perlでアクセサメソッドを作ろうとするとちょっぴりコード量が膨らみます。
ようは引数があればSetterと見なし、引数がなければGetterと見なすという感じです。

これをもっと簡略化してくれるCPANモジュールのMooseが気になるところです。

RubyのSetter・Getter

Rubyではそもそもオブジェクトの外部からインスタンス変数を直接参照することができないので、アクセサメソッドが必須になってきます。

以下の例は自分でアクセサを作った場合


でもこれを属性分作るのは面倒なので、以下のように簡単にアクセサメソッドを作ることができます。
ここらへんがRubyっぽいですね。

JavaのSetter・Getter

Javaのアクセサはみなさんご存知ごくごく一般的な感じ。
まぁこれでもEclipseの自動生成を使えば、Getter・Setterは自動で作ってくれるので便利と言えば便利なんですけどね。

まとめ

JavaScriptはやっぱり今の時点でもクロスブラウザの問題が出てきてて、実際に使われるのかどうかそのあたりが難しいところですが、
でもこうして見てみると昔のJavaScriptでは考えられないほど使いやすくなっているような気がします。

Rubyのように1行書けばよいのもあれば、setNameのように自前でメソッドを作らないといけないJavaなんかもあったり言語間ではバラバラなのはしょうがないですね。
いろんな言語を跨ぐと、この言語はどうだったっけかな?みたいに迷ってしまいそうですw

どうしてアクセサメソッドなんて面倒なものを使わないといけないのかは以下のリンクを参考にしてください。
オブジェクト指向プログラムでgetter/setterメソッドを使わなければならない10の理由

JavaScript版Box2dを手軽に使えるようにprotoBox2d書いてみた

Box2DJS - Physics Engine for JavaScript

ActionScriptで有名な(確か元はC++だったような)Box2dのJavaScript版がいつの間にか存在していたので手軽に扱えるようにprotoBox2dを書いてみました。
Box2d自体がprototype.jsを必須にしているので、やむなくボクもprototype.jsで書きました。
ここ最近jQueryばっかだったから正直prototype.jsがきつく感じられた。

一応IE6でも落下のみはできるのですが、すんごい重いです。
IE7はドラッグアンドドロップまでできるようにしてあります。ただこちらも重いです。

Webkit系のブラウザのSafariGoogle Chromeで試してください。ホイホイ投げれます。

デモ、詳細は以下からどうぞ。
protoBox2d.js - Box2d JavaScript Library

[via]
sasapong's room

jQueryでマウスから逃げるRunAwayFromMouse書いてみた Part2

RunAwayFromMouse.js

jQueryでマウスから逃げるRunAwayFromMouse書いてみたで書いたコードを改良して、マウスが動かなくなっても元の位置に戻ろうとするようにした。

それと逃げる範囲を大きくしたので、バラける感じがうまく表現できたと思う。

今まではマウスが動いたたびにmousemoveイベントでエレメントの個数分ループさせていたのですが、これだとめちゃくちゃ遅くてまずはここを以下のように改良した。

mousemoveイベントのコード

このイベント時はマウス座標を変数に格納するだけを行い、エレメントを逃げさせる処理は別のタイマーで書いた。
それが以下。

タイマーでエレメントを動かすコード

一応60ms単位でエレメントを動かしているが、もう少し感覚を短くしても問題はなさそうだ。
ただしやっぱりFirefoxだともっさりしてしまうので、大体60ms程度が望ましい。

動作は以下のリンクからどうぞ。

RunAwayFromMouse.js

まとめ

マウスの座標はmousemoveなどのイベント時じゃないと取得できないので、このイベントでは最小のコードを実行して、別スレッドでエレメントを動かすという発想はマウスから逃げるように文字が移動するJavaScriptから拝借した。

こうゆう最適化って一見面倒そうに感じますが、やってみると体感がいい感じになるので突き詰めていきたい感じです。

jQueryオブジェクトから配列に変換してくれるmakeArray

jQueryオブジェクトに複数のエレメントが格納されてて、これらをまとめた配列なんかが欲しいときに便利な関数。

lengthプロパティを持っていれば配列に変換してくれるようなので、独自なオブジェクトにも使えそう。

使い方は以下のような感じ。childrenで複数の要素を持つjQueryオブジェクトを配列に変換しています。

これ初めて使いましたw

画像がグルグル回るjQuery Plugin - jMerrygoround作りました

jMerrygoround - jQuery Plugin

仕事の一環で作ってみたのですが、使わなかったのでリニューアルして公開してみます。
普通に回るのはすでにあったりするのですが、ちょっとオモロ〜に回してみたいという方向けに作ってあります。
デモのところでいろいろ遊んでください。

この命名ははじめjSliderとかそのあたりの名前にしようかと思ったんですが、いまいちパッとこなくて、嫁さんに画像が回るのを見せながら「これ例えるなら何かな?」って聞いたら「メリーゴーランドだね!」と回答がきたので決定しましたw

追記:fukkenさんのいうカルーセルという名前もすでに結構使われてて、これは速攻でやめましたw


デモ、詳細は以下からどうぞ。
jMerrygoround - jQuery Plugin


あとキングボンビーがサイトを侵略する?jQuery Plugin - kingbonbi.js作りましたダンスっぽいことしたいと言っていたのでjMerrygoround Demo - actionMouseoverKingbonbiなんかも作ってみました。

Firefoxのリンクをクリックしたときの点線を消す方法

Twitter / 30DB30FC30E0

JavaScriptでaタグをクリックしてアニメーションさせるときとかに気になりがちな点線をCSSで消す方法です。

[via]
CSS Hacks and Issues

jQueryでマウスから逃げるRunAwayFromMouse書いてみた

untitled

マウスから逃げるFlashがかっこいいで紹介したFlashをJavaScriptで書いてみた。
マウスの移動に伴って回りの要素が逃げるように動きます。

canvasタグとdivタグの2パータンで作ってみたんですが、どちらもFlashとくらべるとかなりもっさりしちゃいますねw
Firefoxでは50個、Webkitでは100個を描画しています。
多分divタグのほうがcanvasタグより軽いです。

なのでSafariかChromeあたりでも見てもらえるとそれっぽくなると思います。

サンプル

コード

つくづく思いますが、jQuery使うとコードも少なくてすむので楽ですね〜。

マウスから逃げるFlashがかっこいい

マウスから逃げる - wonderfl build flash online

このぼやけた感じがすごいネオンぽくてすてきです。

AS?? - wonderfl build flash online

こっちのクリアな丸がなんかブドウっぽくてかわいい。


今日はこの2個のFlashを見て遊んでた。
自分でいろいろカスタマイズできるのが、このwonderflというサイトの特徴なんですが、
面白法人カヤックもなかなか良いサイト作りますな。

jQueryでサイト内リンクを使ってSmoothなScrollをする方法

追記(2009/03/30):
hashがない場合にreturnするように修正。
これがないと<a href="#">とかの場合にスクリプトエラーになるため。

サイト内リンクでアンカータグにhref="#hoge"なんて指定している場合に使えそうなscroller

これで自動でアンカータグをクリックするとアニメーションしながら目的値のところまでスクロールしてくれる。

^は初めの文字が#だった場合という意味なので、*にしてもよいかも。
もしhref="http://hoge.com/#hoge"とかの場合にはこの方法が有効。

こんなもんでいいのかな?
なんかさらにもっと簡単な方法がありそうだけど。

画像に水面の反射のような効果を付けられるReflector.js作りました

Reflector

既存であったりするんですが、自分が使いやすいように作ってみました。
以下の2パターンで画像のリフレクションを設定することができます。

reflection="true"が指定されたエレメントを一括でリフレクションさせる場合は以下のように記述してください。

エレメントを引数に渡してひとつの画像をリフレクションさせたい場合は以下のように記述してください。

詳細は以下のリンクからどうぞ。
Reflector.js - JavaScript Library

WiiリモコンからTwitterにPostしてみた

前に胎児がTwitterにPostする? - kickbeeBluetooth経由でお腹にいる赤ちゃんのキックをPostするというのを紹介したのですが、ためしにWiiのリモコンからやってみても面白いかも!ってことで試してみました。

最終的にはWiiリモコンの押したボタンをTwitterにPostするようにしてみます。

開発環境

まずは今回試した環境を以下に記載します。

OS
Mac OS X Leopard
JDK
1.5以降
BlueTooth
必須
コントローラー
任天堂Wiiリモコン

JDKが1.5以降となっているのは、今回使ったライブラリが1.5以降を必須としているためです。

どうやって通信するの?

Wiiリモコンと会話するにはBlueToothが必須になります。
そしてBlueToothから来たパケットを処理してどのボタンが押されたのか、または今どの座標にいるかなどを取得する必要がありますが、そういった基本機能はすでにライブラリとして提供されています。

なのでまずは簡単にライブラリの説明をして、その後実際にコードを書いてみたいと思います。

BlueCove - JSR082 API

JSR082 APIというのはBlueToothにアクセスする基本的なインターフェースを提供してくれます。
そしてMacやPC用に作られたオープンソースなライブラリは、「BlueCove」になります。

以下からbluecove-2.1.0.jarをダウンロードしました。
Downloads - bluecove - Google Code

WIIREMOTEJ

WiiRemoteJはMac OS XとWiiリモコンを繋ぐインターフェースを提供してくれるライブラリです。
先ほどのJSR 82を使ってWiiリモコンを探し出し、細かいプロトコルの変換なども自動で行ってくれるすぐれたライブラリです。

以下からWiiRemoteJ v1.6.zip.gzをダウンロードしました。
Index of /WiiRemoteJ

WiiリモコンとMacを繋いでみる

ボクは今回Eclipseを使って開発を行いましたのでその手順を以下に記載します。
まずは上記2つのライブラリをプロジェクトにドラッグし、ビルドパスを通しておきます。

WIIREMOTEJをダウンロードすると付属してくるファイルの中から

  • WRLImpl.java
  • Audio.au

をプロジェクトに追加します。
WRLImpl.javaはWiiリモコンとの基本的な操作が書かれたサンプルで、この中に今回使うエッセンスがぎっしり詰まっています。
またAudio.auは40秒間のサウンドクリップになりますが、JavaからWiiリモコンに音を出すときに使います。
もし音は出さなくてもよいという人はプロジェクトに含めなくても大丈夫です。

そしてWRLImpl.javaを実行してみます。

BlueCove version 2.1.0 on mac

とコンソールに表示されると思います。

このタイミングでWiiリモコンの1ボタンと2ボタンを同時押しします。
するとWiiリモコンの4つのライトが点滅しますので、コンソールを見て少し待ちます。

少しするとコンソールにいろいろ出力されますが、

java.lang.IllegalStateException: Devices are already being found! Only one "find" operation may run at once.

と表示されいっこうにスタンバイ状態にならなかったので、ハマりましたw
調べてみると海外の人で同じ現象になってる人がいました。
WiiLi.org java.lang.IllegalArgumentException: PCM values restricted by
に書いてあったのですが、

をMainメソッドの一番初めて入れればうまく動きました。

これでまた先ほどと同様にWRLImpl.javaを実行し、Wiiリモコンの1ボタンと2ボタンを押してみます。
Javaが起動してから3秒後くらいにボタンを押すとエラーになりにくくなりますが、もしうまく接続できない場合は何度か試してみてください。(なかなか一発で繋がりません・・・)

エラー内容が、

Failed to connect remote. Trying again.

の場合は一回Java側を停止さえてもう一度起動したほうが早く繋がるようになると思います。

とりあえず遊んでみる!

繋がったらWiiリモコンを振ってみたり、各ボタンを押してみるとコンソールにその情報が表示されると思います。
この時点ですげ〜感動!!

Accelerometer graph: Wii Remote

振ると画面の表示もこの画像のようになると思います。
とりあえずこれでうまく繋がりました。

TwitterにPostしてみる

先ほどのWRLImpl.javaをサンプルにして、以下のコードを書いてみました。
WiiRemoteJ.findRemote()が実際にWiiリモコンを探し出すコードです。このメソッドを呼ぶだけでWiiリモコンと繋がるなんてめちゃくちゃ便利!

addWiiRemoteListenerにリスナーをセットし、buttonInputReceivedメソッドは、ボタンを押したら呼ばれる部分になります。
なので、この部分にどのボタンを押したかをTwitterにPostする処理を入れています。
TwitterにPostする処理はTwitter4Jを使わせていただきました。

gist: 82868 - GitHub

結果:
P3:PeraPeraPrv

ほとんど自分でコードを書かなくてもこれぐらいのことができちゃうのがすごいですね。

番外編 - Wiiリモコンから音を出してみる

先ほどのAudio.au音楽ファイルを使ってWiiリモコンから音を出すサンプルです。
まぁWiiリモコンのスピーカーなので、あんまり音はでないですが、とりあえず何となく音は聞こえたのでよしとします。

gist: 82871 - GitHub

YouTubeでWiiリモコンからナイトライダーを流す動画がありました。
こんなにちゃんと音出るのかな?

Knight Rider Wii Remote

まとめ

ライブラリが充実していてほとんど自分でコードを書かなくてもこれぐらいのことができちゃうのはやっぱりすごいことですね。
動かなくて四苦八苦はしましたが、ハマるというのもこうゆう遊び感覚のコーディングの楽しいところです。

あとSourceForge.net: DarwiinRemote: Filesというアプリを使うとWiiリモコンでマウス操作ができるようになるのですが、ボクの環境なのかほとんど使いもんにならなかったですw

■参考リンク
WiiLi.org Wii Linux - JP:WiiremoteJ/Installation
WiiLi.org Wii Linux - JP:WiiremoteJ/ReadMe
JavaとWiiリモコンをBluetoothでつなげてみよう - ブログ: 岡崎 - Okazaki's blog
BlueCoveConfigProperties ( bluecove 2.1.1 -スナップショットAPI )を

JavaScriptで関数内のthisを文字列にする方法

jQuery() の挙動を解読する(29) jQuery.css() クラスメソッド upon ver1.3.2──jQuery解読(43)を読んでいて、jQueryのeachではthisが第1引数(文字列とか)になると書かれていたので実際に試してみた。

ソースコード

どうやら文字列を渡すとnew String()を行った状態で呼び出し先関数のthisにセットされるみたいですね。
そのthisと文字列結合をするとobject型からstring型へ自動でキャストしてくれます。

う~ん、今まで文字列なんて渡したことがなかったのですごい新鮮w

jQueryの場合

-webkit-transformを使ったCSSアニメーションを試してみた

Safari3.1以上で搭載されたCSSプロパティ-webkit-transformいまさらながら試してみた。
ChromeかSafari3.1以上で触ってみてください。

-webkit-transitionでアニメーションさせるCSSプロパティを指定して、例えばhoverでそのCSSプロパティの値を変更すればJavaScriptで実行しているようなアニメーションをしてくれる。

また-webkit-transform-originに50%を渡しているが、これはデフォルト50%なので特に意味はない。

translate、scale、rotateの合わせ技

透過

クリックで回転

ボーダー伸び縮み

※注意:0pxにするときにsolidがないとアニメーションしてくれない。


■関連リンク
Surfin’ Safari - Blog Archive ≫ CSS Animation
Weblog  Safari 3.1でやってみたかった3つの事
The Art of Web ~ CSS: Animation Using CSS Transforms

Twitterがクリックジャッキングを防止している方法

いつの間にかクリックジャッキングという脅威が発見されて、これはこれで恐ろしいな~と思いメモしとく。

クリックジャッキングとは、透過指定されたiframeなどの要素に標的サイトのコンテンツを読み込み、これを攻撃者サイトの要素よりも上に配置することで、Webブラウザの画面上には攻撃者サイトの要素だけを表示させ、その上でユーザーが行うクリック操作を標的サイトに対して行わせるもの。


via:
主要ブラウザすべてに影響する「クリックジャッキング」攻撃とは

なかなか巧妙だが確かにできる手法ではある。
また透過されているのでサイト訪問者は攻撃者サイトを見ていると思い込んでいるが、実は標的サイトが前面にきているのでもしボタンやテキストボックスの位置をうまいこと偽装すると容易にログイン情報などを盗み取れてしまう・・・怖い

2月にもTwitterがこの攻撃を受けて意図しない投稿をさせられてしまうという事例があったそうな。
んで、ローカルでiframeを読み込むHTMLを作成し、「http://twitter.com/home」を読み込んでみた。

一瞬普通にTwitterのホーム画面が出るが画面のレンダリングが下のほうに達すると何も表示されなくなったので何かしら対応したのだろう。

どのように対応したかは以下のソース。

攻撃者サイトがiframeで標的サイトを読み込んでいる

まずここでは標的サイトをiframeで読み込む。

標的サイト側ではwindow.top !== window.selfで不正に読み込まれたか判断している

window.top !== window.selfで自分自身がtopでない場合にinnerHTMLを空文字で上書きしている。
確かにこれならクリックジャッキングを防げそうだが、ブラウザのscriptが無効になっていると意味がない。

対応策

IE8 RC1にクリックジャッキングの問題を解決した機能が実装されているようだが、これはIE8の普及率に依存しそうだ。

FirefoxユーザーならクリックジャッキングにFirefox+NoScriptで対抗できるのか?で紹介されているNoScriptを入れて「<IFRAME>の禁止」にチェックを入れれば防げそうだ。
だたGoogle Adsenseはiframeを使って広告を出しているから、広告費で生計を立てている企業からするとこれはこれで痛そうだw

現時点ではこれぐらいしか防ぐ手立てがないようなので、信頼していないサイトでは閲覧のみにして入力するなどは控えめにしたほうがよさそうということですね。

CSS3のbox-sizingでpadding・borderをwidth、heightに含めてみる

CSS3 Basic User Interface Module

一般的にエレメントのwidthやheightはpadding・borderなどは含まないがこれを含めるかどうか指定できるのがこのbox-sizingだそうだ。

たとえばCSS3 box-sizing attribute - Helephant.comに書いてある画像を見てもらえれば分かるが、2個のfloatしているdivタグがあり一方は「width:30%」、もう一方は「width:70%」としている。
この場合は1pxでもpadding・borderなどがあると下に滑り落ちてしまうのだが、これを防ぐためにbox-sizingを使っている。

box-sizingで指定できるのは以下の値になる。

content-box
padding・borderを含めない
border-box
padding・borderを含める

ちなみにまだOpera以外のブラウザではbox-sizingと記述しても機能しない。
独自実装な-moz、-webkit、-ms-boxをプレフィックス付与して記述する必要がある。

box-sizingを使った例

box-sizingを指定しないパターンから指定したパターンで試してもらうと分かるのですが、id="div2"が下に落っこちない!
当たり前だがmarginを指定すると落っこちます。

使えるブラウザ

  • Firefox2以上
  • Safari3.1以上
  • Chrome0.2以上
  • Opera9.6以上
  • IE8以上

[via]
When can I use...

IETesterで試してみたが、一応Beta2では使えたお。

HTMLタグにカスタムな属性を追加しJSから取得する方法

HTMLタグにカスタムな属性を追加しJSから取得する方法

なんかいまさらな気もしますが備忘録として。

たとえばdojoなんかを使っていると以下のようにエレメントの属性に見たこともないのが書いてあったりする。

dojoのカスタム属性の場合

scriptタグのdjConfig、divタグのdojoTypeがそうですね。

自前のカスタム属性の場合

これを単純に自前でやってみる。

divタグにhogeという属性を書いて見ていざelem.hogeで値を表示しようと試みるがFirefoxでundefinedが返ってきてしまう。
でもIEではうまく取れた・・・

なんでだろう・・・

とりあえずFirebugで追ってみた。

まずはelemオブジェクトを見てみる。

一生懸命hogeプロパティを探してみるが見つからない。だがidプロパティは存在している。

次に属性としてちゃんと登録されているか確かめてみる。

として、attributesの中身を拝見。

item(0)
Attr nodeName=hoge nodeValue=hoge nodeType=2
item(1)
Attr nodeName=id nodeValue=hoge nodeType=2 childNodes=[1]
length
2

一部割愛したが属性の個数が2個になってる!
そして0番目にはnodeName=hogeと、hoge属性が格納されていた。

まとめ

普段あんまり気にしていなかったが、自分で追加した属性値はelem.hogeと書いても取得することができない。(Firefoxだと)
なので以下のようにして取得すること!

ちなみにjQueryを使っているなら以下のように書くからあんまり気にしないでも問題ないですね。

NodeList・HTMLCollectionを返すメソッド一覧

かなり個人的なメモですが、NodeList型や、HTMLCollection型を返すメソッドをまとめてみました。
また資料がDOM Level 1と古かったりもするので、必ずしも今のDOMレベルに合っていないかもしれません。

NodeListのメンバ

length
このプロパティは int 型である。
item(index)
このメソッドは Node を返す。index パラメータは unsigned long 型である。

HTMLCollectionのメンバ

length
このプロパティは int 型である。
item(index)
このメソッドは Node を返す。index パラメータは unsigned long 型である。
namedItem(name)
このメソッドは Node を返す。name パラメータは DOMString 型である。

NodeList型を返すメソッド

Document

getElementsByTagName(tagname)
このメソッドは NodeList を返す。tagname パラメータは DOMString 型である。

Node

childNodes
このプロパティは NodeList 型である。

Element

getElementsByTagName(name)
このメソッドは NodeList を返す。name パラメータは DOMString 型である。

HTMLDocument

getElementsByName(elementName)
このメソッドは NodeList を返す。elementName パラメータは DOMString 型である。

HTMLCollection型を返すメソッド

HTMLDocument

images
このプロパティは HTMLCollection 型である。
applets
このプロパティは HTMLCollection 型である。
links
このプロパティは HTMLCollection 型である。
forms
このプロパティは HTMLCollection 型である。
anchors
このプロパティは HTMLCollection 型である。

HTMLFormElement

elements
このプロパティは HTMLCollection 型である。

HTMLSelectElement

options
このプロパティは HTMLCollection 型である。

HTMLMapElement

areas
このプロパティは HTMLCollection 型である。

HTMLTableElement

rows
このプロパティは HTMLCollection 型である。
tBodies
このプロパティは HTMLCollection 型である。

HTMLTableSectionElement

rows
このプロパティは HTMLCollection 型である。

HTMLTableRowElement

cells
このプロパティは HTMLCollection 型である。

番外編

基本的に↑に書いたメソッドやプロパティはLiveなNodeList、HTMLCollectionになる。
ただし、以下のquerySelectorAllメソッドはStaticなNodeListが返るという仕様?(バグ?)だそうだ。

たとえば以下のようなコードを実行してもらえば分かるだろう。

Selectors API

querySelector
このプロパティは Element 型を返すので今回のとは違うな。
querySelectorAll
このメソッドは NodeList を返す。name パラメータは DOMString 型である。

querySelectorAllがliveじゃないNodeList返すのはなんで? - vantguarde - web:gでもあるようにliveじゃないStaticNodeListが返るめずらしいメソッド。

参考にした資料

付録 E: ECMAスクリプト言語バインディング

Document Object Model (Core) Level 1
Document Object Model Core Level 2
Document Object Model Core

第23回 NodeListインターフェイスを利用する
Web Kit DOM Programming Topics: JavaScriptからのドキュメントオブジェクトモデルの使用

FirebugがXMLHttpRequestを監視している方法を読んでみる

JavaScriptを使って何か物を作っている人はまず間違いなくFirebugを使っているというほどFirebugは世の中のJavaScripterに浸透しています。

alert文をひたすら書いてデバッグしていた時期が懐かしいです。(今でもalertを使うことはありますが)

そして一番楽になったといえばAjax関連の開発が昔と比べて格段に楽になりました。
これはAjaxリクエストが送信されたタイミングと応答が返ってきたタイミングでFirebugがコンソールに内容を出力してくれるからだと思います。
これ以外にもどれくらい通信速度がかかったかなども見ることができるのでとってもありがたいです。

そんなAjaxの監視をFirebugが一体どうやってやっているのかをここで紹介してみようと思います。

Firebugインストール

Firebugがまだ入っていない人はFirefoxを立ち上げてFirebugを入れてみましょう!

Firebug :: Firefox Add-ons

ソースコードの場所

ボクの環境では以下の場所にFirebugが置いてあります。

C:\Documents and Settings\hogeuser\Application Data\Mozilla\Firefox\Profiles\yrljtiye.dev\extensions\firebug@software.joehewitt.com

もうみなさんも慣れて来たと思いますが、実際のコードはこのディレクトリのcontentフォルダの中にあります。
ここにJavaScriptやらxulやらCSSなどがゴロゴロありますが、今回見るファイルはそんなに多くはないので大丈夫です!

ソースコードリーディング

ボクはこの手のソースコードを追う場合は、まずは関連しそうなキーワードでgrepしちゃいます。
たとえば今回はAjax部分の監視をしている箇所なので、おそらく「XMLHttpRequestがなんたらかんたら」みたいな部分がありそうだな~なんて。

なので「XMLHttpRequest」でgrepし、そこからソースコードリーディングを始めてみたいと思います。
grepする範囲はcontentディレクト内の全ファイルからということにしてみます。

またコードの量がそこそこ多いので、メソッドの中とかかなり端折った形で紹介していきますのでご了承ください。

net.js

XMLHttpRequestをキーワードにgrepした結果、net.jsがとってもあやしそうです。
2047行目にinstanceofでXMLHttpRequestかどうかを判断している箇所があるので、なんとなくここっぽいですね。

2047行目

では次にここのgetRequestWebProgressメソッドを呼び出している箇所に飛びましょう

どうやら同じファイルの2658行目のonModifyRequestメソッドから呼ばれているみたいです。

2658行目

onExamineResponseメソッドからも呼ばれているようですが、onModifyRequestメソッドのほうがネーミング的にとっつきやすいのでとりあえずこっちでw

ではさらにonModifyRequestメソッドを呼び出している箇所に飛びましょう

すぐ上にあるobserveというメソッドが読んでいるようです。
ここまでの時点でなんとなく見えてきましたね。

リクエストが送信されるタイミングでonModifyRequestメソッドが呼び出され、その中のgetRequestWebProgressメソッド内でXMLHttpRequestかどうかを判断しているという感じです。

ではobserveがいつ呼ばれるのかが知りたいところ。
とりあえずobserveでgrepをしてみたもののいまいち呼び出している箇所がなさそうです。

リフレクションだと見つけにくいな~なんて思っていたら、registerObserverというメソッドがあるのに気がつきました。
う~ん、登録しているのか~。あやし~い~。

ということで2609行目のregisterObserverを見てみます。

2609行目

なんとなく2種類のイベントにHttpObserverというオブジェクトを渡しているのが確認できます。
実はこのhttp-on-modify-requestというイベントが今回のキモになります。
http-on-modify-requestとは

http リクエストが作られたときに呼ばれます。通信路 (channel)
はヘッダーなどの変更などが可能です。


via: Observer Notifications - MDC

とhttpリクエストが送信されたときに呼ばれるそうです。
さらにaddObserverメソッドの第1引数には、nsIObserverインターフェースを実装したオブジェクトを渡すようにと書かれています。

[scriptable, uuid(DB242E01-E4D9-11d2-9DDE-000064657374)]
interface nsIObserver : nsISupports {
void observe( in nsISupports aSubject,
in string aTopic,
in wstring aData );
};

nsIObserver - MDC(肝心な部分が英語ですがw)
nsIObserverService - MDC

ということはリクエストが送信されたタイミングで、イベントhttp-on-modify-requestにセットされたHttpObserverオブジェクトのobserveメソッドが呼び出されるという仕組みになりますね。

やっとobserveが呼び出されるポイントがつかめました。
先に進みましょう!

次はイベントを登録していたregisterObserverメソッドを呼び出している箇所です。

grepした結果192行目で呼び出しているようです。

192行目

じゃあこのinitializeUIメソッドを呼び出している箇所はというと・・・
grepしてみても他のオブジェクトのinitializeUIメソッドは呼ばれているようなんですが、肝心なFirebug.NetMonitorのinitializeUIメソッドが呼ばれている箇所が見当たりません。

・・・

実は2804行目でFirebug.registerActivableModuleメソッドにFirebug.NetMonitorを渡しているようです。

2804行目

なんとなく見えてくるのがinitializeUIはどうやら登録しておけば勝手に呼ばれるメソッドなの?みたいな。

firebug.js

実は登録したメソッドを呼び出している箇所がfirebug.jsの224行目になります。

224行目

このメソッドの

がそれにあたります。

Firebug.registerActivableModuleメソッドで登録しておいたinitializeUIをdispatch関数がリフレクションで呼び出してくれている感じになります。

ではFirebug.initializeUIメソッドはダレが呼んでいるのかと。

chrome.js

chrome.jsの157行目に

157行目

となっているのでおそらくこの部分ですね。

ではさらにさかのぼってFirebugChrome.initializeUIを呼んでいる部分へ!

1043行目のbrowser1Loadedという関数の中にありました。

1043行目

さらに次~!

browser1Loaded関数は102行目で

102行目

ほほぅ、loadイベントですね。分かります!
これは拡張がロードされたタイミングのイベントになりますね。

さらに次~!

initializeメソッドを呼び出しているのはすぐ上のpanelBarReadyメソッドになります。

58行目

bindings.xml

最後のFirebugChrome.panelBarReadyメソッドは実はJavaScriptファイルからの呼び出してではなくbindings.xmlというbindingを定義しているファイルからになります。

id="panelBar"というbinding要素が生成されたタイミングでconstructorタグ内の処理が呼ばれます。
このときにFirebugChrome.panelBarReadyメソッドを呼び出しているということですね。


これでやっと、


FirebugにAjax通信したときに表示される仕組みが分かりました!


最後のほうはグダグダでしたが、なんとなくFirebugがXMLHttpRequest送信時にconsoleにログをはく仕組みを理解していただいたと思います。
普段使っているだけあって、こうゆうところにも注意して見てみると面白いですね。

番外編:いつも使っているエディター

ボクがつかっているエディターはPeggyというエディターでシェアウェアですが、1ヶ月のお試し期間があります。

あんまり使っている人がいないようですが、ボクにとっては最強のエディターです。
オススメな機能はプロジェクトを持てることですね。

プロジェクトを作成して、例えばFirebugのソースを一式登録しておけばいつでもプロジェクトファイルを開くだけで見ることができます。
ボクの中では軽いIDEみたいな扱いになってますw
あとスニペットもデフォルトでかなり入っていて、自分で登録も簡単にできるのでJS書くときは便利です。

「func」まで入力したら後はCtrl+/でインテリセンスみたいな。

MacのときはTextMateですね。
PeggyはWindow版のTextMateみたいな感じで使ってます。(スニペットがヤヴァ過ぎる!)

Ruby on RailsのコーディングスタイルにTextMateは最適ですが、jQueryやPrototype.jsのコーディング時にも役にたちます。

拡張的な参考記事

Firefox拡張機能(Extention)の簡単な作り方メモFirefox拡張機能(Extention)の簡単な作り方メモ Part2


続きで簡易版XMLHttpRequest監視Extentionを紹介してみます。

Continue reading

Google Visualization APIメモ

まだあんまり使ったことなくて、ちょこっと調べたのでメモメモ。

コードは以下のようにVisualization APIをloadするかたちで使用する。
そのとき使いたい表示コントロールをpackagesに渡す。

もし複数の表示コントロールを使いたい場合は以下のように配列に複数入れると可能。

サンプルコード

行をクリックすれば色が変わるし、列Titleをクリックすればソートされる。
これは便利だな~。

google.visualization.Query

を使ってAjaxクエリを発行できるが、個人的にはこのTable機能単体で使う可能性あり。
Ajaxは別の方法で取得する。

ドキュメントなどなど

本家ドキュメントはGoogle Visualization API - Google Codeより。

和訳もGoogle Visualization API - Using Visualization : Overview の和訳 その1|株式会社 フラッツで見ることができます。

こちらでGoogle Visualization APIを使ったサンプルをコード付きで見ることができます。
AJAX APIs Playground

[via]
はてなブックマーク - monjudohのブックマーク

■参考リンク
Google Visualization APIを早速使ってみた - builder by ZDNet Japan

Rails2のto_jsonで簡単にJSONを返す方法

Rails2からto_jsonというメソッドが使えるようで、Mapに対してto_jsonしてやると簡単にJSON形式で返すことができるみたい。

controller.rb

index.json.erb

index.html

結構Jsonパーサーみたいなのを作るのってしんどいからこうゆうのすごい便利!

■参考リンク
Rails2.1でSWFUploadを使うの続き。JSONでレスポンスの続き - Paradigm Shift Design

Rails2をインストールするときのメモ

rubyのバージョン:1.8.6

Railsのインストール

いつものgemを使ったインストール。

gem install rails

しかしgemが古いとかでエラーが出てしまったのでアップデート。

gem update --system

んでまた、

gem install rails

今度はエラーなし。

rails --version # Rails 2.2.2

入った!

SQLiteのインストール

Rails2.0.2からデフォルトDBがSQLiteになったようなので、SQLiteを入れる。

SQLite Download Pageにコンソール用のexeとdllをダウンロードしにいく。

ダウンロードしたdllファイルとdefファイルをパスが通ってるruby\binにコピー。
(のちのちruby ./script/dbconsoleなんかを使うならexeもコピーしとく)

これだけではSQLiteがrubyから使えないので、sqlite3-rubyをインストール・・・

gem install sqlite3-ruby

がエラーが出た。

C:\_\rails>gem install sqlite3-ruby
Building native extensions. This could take a while...
ERROR: Error installing sqlite3-ruby:
ERROR: Failed to build gem native extension.

c:/ruby/bin/ruby.exe extconf.rb install sqlite3-ruby
checking for fdatasync() in rt.lib... no
checking for sqlite3.h... no

nmake
'nmake' は、内部コマンドまたは外部コマンド、
操作可能なプログラムまたはバッチ ファイルとして認識されていません。


Gem files will remain installed in c:/ruby/lib/ruby/gems/1.8/gems/sqlite3-ruby-1.2.4 for inspection.
Results logged to c:/ruby/lib/ruby/gems/1.8/gems/sqlite3-ruby-1.2.4/ext/sqlite3_api/gem_make.out

調べてみたら因果律量子論 Ruby on Rails nmakeがありませんに解決策が書いてあり、

sqliteのバージョンが新しい物は、ソースインストールみたいなイメージらしくnamekeが必要らしい。
>gem install sqlite3-ruby -v 1.2.3.2.3'

これで、インストールがうまくいくみたいだ。

via: 因果律量子論 Ruby on Rails nmakeがありません

とのことなので

gem install sqlite3-ruby -v 1.2.3

で一つ前のバージョンをインストールした。

プロジェクトの作成

rails hoge -d sqlite3

-d sqlite3」でDBを指定して実行すると、database.ymlがそれ仕様になってくれる。

development:
adapter: sqlite3
database: db/development.sqlite3
pool: 5
timeout: 5000

雛形を作成する。

ruby script/generate scaffold hoge name:string age:integer

んでマイグレーション。

rake db:migrate


以下にアクセスしておきまりの画面が出れば成功!

http://localhost:3000/hoges

■参考リンク
Rails 2.0のscaffoldを使ってみた - idesaku blog
Ruby on Railsインストールメモ - rubyco(るびこ)の日記

JavaScriptでロールオーバーアニメーション Part3

JavaScriptでロールオーバーアニメーションJavaScriptでロールオーバーアニメーション Part2に引き続きであんまり変わっていないんですが、こうゆうのも面白いかも。

今までは高さ20pxのdivタグを横にスライドさせていて、いわゆるプログレスバーっぽさがあったのですが、今回は高さ0pxにしておいて横にスライドするタイミングでじょじょに高さ20pxになるようにしてみた。

続きで動作確認。

Continue reading

JavaScriptでロールオーバーアニメーション Part2

JavaScriptでロールオーバーアニメーションに引き続きマウスオーバー時のアニメーションをJavaScirptで実装しています。


trick7 - ロールオーバー効果へのこだわり2を読んで、dajistudioさんのサイトのアニメーションで気になっていたことがすべて分かった。

たとえばいっきにマウスオーバーした場合は、すこしアニメーションが遅れる。
ただし1つ1つゆっくりとマウスオーバーするとアニメーションに遅れはない。

このレベルは使っている人はほとんど見つけられないと思うけど、なんだか心地よい感じがするのは確かだろうね。
無意識に作用するアニメーションほどかっこいいものはないっ!

なので、この遅延アニメーションをJavaScriptで実装しました。
たぶんタイマーを使っているんじゃないのかな?本家のほうは。

JavaScriptソースコード

jQueryのdataメソッドを使って、マウスオーバーのアニメーションが終わっているのかどうかのフラグ判定しています。
これにより、マウスオーバー直後にマウスアウトしてもアニメーションは終わっていないので、このタイミングで遅延アニメーションを実行します。

続きで動作確認。

Continue reading

JavaScriptでロールオーバーアニメーション

trick7 - ロールオーバー効果へのこだわりを見て、うわ~最後のほうをTweenさせるだけでこんなに気持ちいのかとJavaScript版を作ってみました。

しかし、やっぱりFlashJavaScriptの違い顕著に出てしまったのですがそれっぽくなったと思います。

JavaScriptソースコード

2つのdiv要素を用意しておいて、1つ目の要素にマウスが乗ったときに2つ目の要素をアニメーションさせています。
1つ目の要素を覆うように2つ目の要素が重なるので、そのタイミングでmouseoverが発生してしまうためz-indexでアニメーションする要素を後ろ側に隠しています。

それとanimateメソッドでwidth:0pxからアニメーションするのではなく、いったんcssメソッドを使ってwidth:200pxまで進めておいて、最後の50pxをアニメーションするようにしています。
このひと手間でオモロ~になりました。

続きで動作確認。

Continue reading

カラフルな要素があっちいったりこっちいったり - xyz.js

ちまたで有名なWonderfl Build Flash Onlineをダラ見してたら、これまた面白いFlashを見つけてしまったのでJavaScriptでソレっぽく再現してみました。

↓これがそのFlash。イカス!
code on 2008-12-23 | Wonderfl Build Flash Online
何個かfoakされているので、他の方のを見てみても面白いです。

ただFlashでできることがJavaScriptでできなかったりもするので完璧に再現はしていませんが、一応それっぽく。
JavaScriptでRotationが使えたら要素をグルグル回せるんですがね。

初めcanvasのrotateを使おうかと思ったのですが、座標の記憶とかtranslateとかややこしそうだったので断念・・・

JavaScriptソースコード

実際のActionScriptで使われているTweenerライブラリの部分はjQueryのanimeteメソッド、easing部分はjquery.easingプラグインを使って補いました。

続きで動作確認できます。

Continue reading

マウスから逃げるように文字が移動するJavaScript

monstropolis.org -- intro10

ここ最近画像を動かすことばかりにハマっていたので、こうゆう文字を移動させるのはすごい新鮮でした。

こまかくspanタグで分割された文字がまるでマウスから逃げるように移動するのがとってもかっこいい。
なんかすごい作りたくなったきたw

コードを見てみると、やっぱり複雑な計算が入っててどうしてもこっちが苦手なんだけど、最近Flexに夢中だからどうしてもさけて通れないんだよね〜。

慣れかな?

monstropolis.org -- intro10

IEではbuttonタグのvalueが取れない

2 IEで<button>のvalueを.val()経由で取得できない


IEでは<button value="value">text</button>の内、value="value"の値を$(this).val()経由で取得することができません。


ただ、これはFirefoxでは正常に取得できるため、IEでは通常のDOM経由でも取得できないのかもしれません。


via: jQueryを使うときに気をつけるべき8のポイント : tech.kayac.com - KAYAC engineers' blog

おお~、なんか懐かしいと思ってちょい実験。
buttonタグっていろいろと問題テンコ盛りですよね。

前に記事にしたIEとFirefoxでテキストボックス上でのEnterの挙動についてでもSubmitするときの情報が変動しちゃうし…

サンプルコード

value経由でもgetAttribute("value")でもやっぱりIEではダメでした。

とりあえずW3C見に行ってみたら。
ほ~ら、ちゃんとvalueってあるじゃ~ん。んもうIE。

<!ELEMENT BUTTON - -
(%flow;)* -(A|%formctrl;|FORM|FIELDSET)
-- push button -->
<!ATTLIST BUTTON
%attrs; -- %coreattrs, %i18n, %events --
name CDATA #IMPLIED
value CDATA #IMPLIED -- sent to server when submitted --
type (button|submit|reset) submit -- for use as form button --
disabled (disabled) #IMPLIED -- unavailable in this context --
tabindex NUMBER #IMPLIED -- position in tabbing order --
accesskey %Character; #IMPLIED -- accessibility key character --
onfocus %Script; #IMPLIED -- the element got the focus --
onblur %Script; #IMPLIED -- the element lost the focus --
>
Forms in HTML documents

jQueryを見に行ってみる

とりあえずjQueryで取れないという話だったので、見に行ってみた。
valメソッドは359行目あたりにあります。

おそろしいほど端折りましたが、大体↑の感じ。
やっぱり普通にvalueを返しているんですね。

buttonタグ恐ろしや…

[via]
jQueryを使うときに気をつけるべき8のポイント : tech.kayac.com - KAYAC engineers' blog

Firefox拡張機能(Extention)の簡単な作り方メモ

Firefoxの拡張はJavaScript、CSS、XMLを使うことにより自作することができるのですが、意外と敷居が高くそこまでドキュメントなんかも豊富ではないので、自分用のメモとして簡単な作り方レシピを残してみようと思います。

開発用のプロファイルを作成する

既存のプロファイルで開発してもいいのですが、いろいろ設定をいじることになるのでここでは開発用のプロファイルを作成しています。

  1. Firefoxを閉じる
  2. ファイル名を指定して実行から「firefox -ProfileManager」で起動する
  3. 適当な名前(ここではdev)でプロファイルを作成する
  4. ファイル名を指定して実行から「firefox -no-remote -P dev」で起動する

これで新しい環境でFirefoxがしたと思います。

開発用に設定値を変更する

Firefoxのアドレスバーにabout:configを打ち込んで、以下の4つの値をtrueにします。

  • javascript.options.showInConsole
    • JavaScriptのエラーをエラーコンソールに出力する
  • javascript.options.strict
    • JavaScriptのエラーを厳密にする
  • browser.dom.window.dump.enabled
    • dump関数によってコンソール(Windowsの場合,コマンドプロンプト)へ文字列を出力可能にする
  • nglayout.debug.disable_xul_cache
    • XULのキャッシュを無効にする

■参考記事
Firefox 3ではじめる拡張機能開発:第1回 最小構成でインストール|gihyo.jp … 技術評論社

んでボクの環境では下の2つがなかったので、
C:\Documents and Settings\user\Application Data\Mozilla\Firefox\Profiles\hogehoge.devにあるprefs.jsに以下を直接設定しました。

これでコードを修正するたびにFirefoxを再起動しなくて済みます。

作業ディレクトリを作成する

Firefoxは通常xpiファイルとして配布されますが、コードを修正するたびにxpiファイルにしてFirefoxにドラッグするとなると、
これは相当な面倒になるので、Firefoxには他の場所にあるソースコードをリンクとして読み込むように設定します。

今回は、

C:\_\firefox\hello ←ここが作業ディレクトリ

のようにフォルダを作成して、Firefoxからこのフォルダを見てもらうようにします。

リンクファイルを作成する

先ほどFirefoxにはソースコードのリンクを指定すると説明しましたが、普通Firefoxの拡張は

「C:\Documents and Settings\user\Application Data\Mozilla\Firefox\Profiles\hogehoge.dev\extensions」

のような場所に存在します。
ここにリンクを作成する感じです。

まずはこのディレクトリ内に「hello@xuldev.org」というファイルを作成しましょう。
そしてファイルの中身に

C:\_\firefox\hello

と書いて、先ほどのディレクトリへのリンクファイルを作成します。
これでhelloディレクトリ内にあるソースコードが読み込まれる感じになります。

クロムマニフェスト(chrome.manifest)の作成

chrome.manifestファイルをhelloディレクトの直下に作成し、以下を記述します。

content hello content/
overlay chrome://browser/content/browser.xul chrome://hello/content/hello.xul

chromeパッケージ名とソースファイルの相対パス指定します。
ここのoverlay宣言ですが、これはFirefoxの画面情報としてで読み込まれるchrome://browser/content/browser.xulに対して
chrome://hello/content/hello.xulも追加してちょみたいな感じです。
これにより自分で追加したメニューなどが表示されることになります。

install.rdfの作成

helloディレクトリ直下にinstall.rdfファイルを作成し、以下を記述します。
ここは作る拡張の情報が記載されているファイルになります。

拡張のバージョンや対応しているFirefoxのバージョンなどを記述します。

以下重要なエレメントだけ説明。

em:id
メアド形式かUUIDで指定します。ここは一意にならなくてはなりません
em:version
拡張機能のバージョン
em:type
2:拡張機能、4:テーマ、8:ロケール、16:プラグイン、などなど
em:optionsURL
メニューのアドオン→設定ボタンを押せるようになります

■参考リンク
Install Manifests - MDC

自作xulを作成する前の事前準備

事前準備としてhelloディレクトリ直下にcontentフォルダを作成しときます。
現状前の構成は、

「C:\_\firefox\hello」ディレクトリの直下に

・contentフォルダ
・chrome.manifestファイル
・install.rdfファイル

がある感じです。

hello.xulの作成

contentディレクトリの直下にhello.xmlxulファイルを作成し、以下を記述します。

ここが実際の拡張に対するxulコードになります。
xml形式でボタンやラベルなどを配置できるので、htmlの知識がある人ならピンとくるはずです。
特にイベント登録でonmousedownを使っているのでまさにJavaScriptですね。

ここで重要なのがstatusbarというタグにid="status-bar"を指定していますが、これは適当につけているわけではなく
すでにchrome://browser/content/browser.xulで定義されているid="status-bar"のstatusbarタグに対するオーバーレイになります。
なので、このid指定を間違えるとステータスバーに表示されなくなってしまうので気をつけてください。

どうゆうidが指定されているかの調査方法は↓のほうに書きます。

hello.jsの作成

↑のxmlのscriptタグで外部jsファイルを読み込んでいるので、それを作成します。
contentディレクトリの直下にhello.jsファイルを作成し、以下を記述します。

単にalertを実行しているだけなので、onmousedown='Hello.alert("Hello")'としちゃってもいいのですが、
ここはサンプルなのであえてそうしてます。

またHelloオブジェクトを作成して、その中にalert関数を入れていますが、ここで読み込まれるjsファイルは
グローバルな環境になってしまうので、すでにありそうな名前のオブジェクトを作ってしまうと他の拡張が動かない場合があります。
(Helloも微妙にあぶないですが…w)

なので、拡張に見合った名前のオブジェクトを作成してその中に関数を追加していくようにしましょう!

アドオン→設定ボタンを押せるようにする

contentディレクトリの直下にprefs.xulファイルを作成し、以下を記述します。
常にデフォルトな設定が読み込まれる拡張なら良いのですが、ユーザーに設定値を選ばせる拡張なら設定ボタンを押せる必要があります。

とりあえずラジオボタンで選べるように作ってみましょう。
preferencesタグのidとradiogroupタグのpreferenceは一致するように指定してください。
ここが間違っているとエラーになってしまいます。

現時点では設定ボタンが押せる状態になるだけですが、後で取得する方法を説明します。

Firefxoを起動してみる

ではとりあえずFirefoxを起動してみましょう!
ちゃんと拡張が読み込まれれば、アドオンを追加したときのウィンドウが表示されると思います。

もしアドオンのウィンドウにビックリマークがある場合はどこかの指定が間違っていることになります。

設定で指定した条件を取得する

Firefox起動のテストがOKなら、次に設定で指定したラジオボタンの情報を取得してみましょう。
まずはhello.xulのonmousedown='Hello.alert("hello")'をonmousedown='Hello.alert()'と引数なしにします。

続いてhello.jsを以下のように変更します。

JavaScriptからXPCOMを利用するには,XPConnectという技術を使います。
XPCOMとはFirefox側で提供している機能をまとめたフレームワークになります。
今回は設定画面で設定した内容を取得するので、XPCOM経由で取得する感じです。

またデフォルト値を設定しておく必要があるので、
helloディレクトリの直下にdefaultsフォルダpreferencesフォルダhello-prefs.jsファイルを作成しときます。

その中に以下のコードを記述してください

これをしとかないと、ユーザーが設定画面でOKを押さない限りthis.getPref("hello", "extensions.hello.")の戻り値が
undefinedになってしまいます。

再テストしてみる

基本的にソースコードを修正したら、Ctrl + Nなどで新しいウィンドウを開けば再読み込みされます。
ですが、install.rdfを修正した場合はそれだけではダメなので、一旦Firefox上で拡張を削除してから
もう一度hello@xuldev.orgファイルをドラッグしてあげましょう。


設定画面で選んだ値がalert表示されたでしょうか?(0 or 1)
よっしゃ~~~!

番外編 - browser.xul内のidを特定する方法

オーバーレイのところでもお話しましたが、オーバーレイ対象のidが分からないとxulを書くことができないので
そのidを探す方法を書いてみようと思います。

以下のをアドレスバーに入力してみてください。

chrome://browser/content/browser.xul

Firefoxの中にFirefoxが表示されると思いますw(なんかすごい)

そしたらFirebugを開いてインスペクター(調査)で目的の箇所をクリックすればそこのxul情報が見れるので、
これでidも特定できますね。

Firebug以外にもDOMInspectorでも同じことができるみたいです。

番外編 - デバッグ方法

デバッグをする方法はボクが知る限り3つあります。

・1つ目はalert表示させるパターンですが、これは普通のJSのデバッグでも有用ですが、
for文とかで回している中でalertするとループのたびにポンッと表示されるのでちょっとうざいです。

alert - MDC

・2つ目はdumpを使う方法ですが、これは試したことがないですw
Firefoxを起動時に「-console」を付けたりしないといけないので、これもまたちょっと面倒です。

dump - MDC

・3つ目はエラーコンソールに出力させる方法です
ボクはこれを良く使います。

ただし、この書き方はFirefox3かららしいです。
今まではXPCOM経由でログを吐かなければならなかったようで、実際には以下のコードになります。

こうゆう関数を一個作ってしまえば問題ないのですが、毎回書くのは難点ですね。
しかもlogという名前の関数だと他の拡張とバッティングしそうなので、もう少し工夫する必要もありますしね。

まとめ

ここまでのことが一通りできたら、他にいろいろ応用できそうですね。
ブロガーなら自分の使いやすいようなcopy+の作成や、Firebugに機能の追加なんかもできちゃいます。

ちょっと面倒ではありますが、作ると楽しいFirefox拡張をどんどん作っちゃいましょう!

Part2へ続く。
Firefox拡張機能(Extention)の簡単な作り方メモ Part2

参考リンク

XUL Reference - MDC
XUL Apps > Tips > prefs.js に設定を保存する・設定を読み込む - outsider reflex
Firefox拡張機能(extension)の作り方 ― ありえるえりあ
FireFox Extensionの作り方

Prototypejsのdom:loadedを検証(IEの場合)

いまさらながらPrototype.jsのdom:loadedがIEでDOMContentLoaded的な扱いになるか試してみた。
普通に使わせてもらっているから、ちゃんと動いているんだろうけど何せ擬似なDOMContentLoadedですからね。

Prototype.jsでは3960行目あたりからdom:loadedの部分になります。
んで、IE版のところは3988行目から。

こんな感じです。

scriptタグを生成して、ロードが完了したタイミングでセットされた関数をfireしています。
ここでscriptタグにはdefer属性が指定されているので、このscriptタグの中にはdocument.writeがないことを条件にしています。
つまり、この部分を遅延評価してね~という感じですね。

この遅延のタイミングがDomContentLoadedと同じ?とみなしているようです。

順番としては、

  1. ブラウザがHTMLを上から順番に評価し始める
  2. JavaScriptからscriptタグが追加されるが、defer属性が入っているのですぐに実行しない
  3. 画面全体のDomが構築される
  4. defer属性が付いていたscriptタグの中身が評価される
  5. よってこのタイミングがDom構築完了を意味する

ほんと?w
いやちゃんと動作するんだからそうなんでしょう。
defer属性をこうゆう風に使うなんて、なんかとっても面白いですね。

サンプルコード

少し重めの画像を適当に用意して、さきほどの擬似DomContentLoadedとwindow.onloadの中でalertを表示されています。
これでどっちが先に呼ばれるかが重要ですね。

結果はちゃんと「dom:loaded」→「onload」の順番でした。
ただし、上の画像がない場合など比較的HTML要素が少ない場合ではonloadのほうがdom:loadedより速かったです。
なので画像を使わないテキストサイトとかだとdom:loadedを待つよりonloadを使ったほうがよさそうですね。

ちなみにjQueryのIE版DomContentLoadedは

以下のように、document.documentElement.doScroll("left")が正常に動くまで実行しています。
これを考えた人は本当にすごいですね。
IEContentLoaded - An alternative for DOMContenloaded on Internet Explorer

なぜ、document.documentElement.doScroll("left")でExceptionが発生しないとDomContentLoadedだと思ったんでしょう。

補足

IEscript要素にdefer属性をつけるとinnerHTMLに代入したscriptが実行されるという仕様がある。


via: script要素のdefer属性の実装 - Thousand Years

なんてこともあるみたいです。

FirebugのmonitorEventsでイベント丸見え

いやはやこれは便利だ。
ここ最近全然使っていなかったが、あらためて使うと便利さが理解できる。

サンプル

で特定のエレメントのクリックイベントを監視。

で特定のエレメントのイベント全部を監視。

NodeList[0]とNodeList.item(0)では戻り値が違う

getElementsByTagNameとかで取得したNodeListから参照したいエレメントを削除して、それから中身を見ようとした場合elems.item(0)とelems[0]では戻り値が違う。
まぁ当たり前といっちゃ当たり前かもしれない。

item(0)は関数で指定したノードがない場合にnullを返す、[0]は直接NodeListを見に行ってそこに定義がないからundefinedかな。

とはいっても、

これはちゃんと通るから、大丈夫かな。

このほうが無難かも。

一応DOMの規定では配列のようにアクセスしても、item関数経由でアクセスしてもいいみたいです。

NodeListをforinするとわ~お

ちなみにNodeListをforinとかで回すとえらいことになる可能性があるので、注意が必要です。

これだと欲しいエレメントのpタグ以外に

  • length
  • item()
  • namedItem()

が取れちゃうから。
なので、普通にfor文で回したほうがよいですね。

高速化するなら

NodeListやHTMLCollectionに直接アクセスするより、一旦静的な配列にしたほうが速い - 素人がプログラミングを勉強するブログ

一旦配列に突っ込んだほうが速いようです。
意外や意外!

ブラウザごとのJavaScriptアニメーション比較

ここ最近JavaScriptでアニメーションする機会が結構増えてきたのですが、やっぱりブラウザによって速度というか動きがかなり違うので、その比較をメモメモ。

IE6.0

IE6.0は以外にもアニメーション処理は速いというか滑らかです。

前にもJavaScriptでアニメーション(animate)するときに気をつけたいことで紹介しましたが、中に画像がたくさんあるdivタグmargin-leftとかでアニメーションすると激重になる可能性があるので注意が必要です。

position:absoluteでのアニメーションはかなり調子良いです。

IE7.0

比較的問題がないブラウザです。

marginを使ったアニメーションにも強いですし、opacityを使って透過してフェードアウトとかにも強いです。
IE7.0は重い重いという話が良くありますが、アニメーションに限ってはなかなか出来るやつですw

Firefox2.0

これが一番曲者かと。

アニメーションする際に対象のdivタグがoverflow:autoになっていると、すごいチラ付きが発生しますし、アニメーション処理自体にもモッサリ感があります。

このoverflowの話は結構面倒で、今まではIEとIE以外のJSコードを分ける処理は結構書いていましたが、Firefoxの場合にもoverflowをhiddenにしたりautoにしたりと独自実装になる感じです。

Firefox3.0

Firefox2.0と比べるとまぁ良いのですが、タブをいっぱい開いていたりFirefoxのメモリ使用量が多いとアニメーション時にもたつく感じがあります。(これはFirefox2.0も同じです)

こちらもoverflowは対策が必要です。

Opera9

Operaのアニメーションはとてもきれいです。 margin、positionとも滑らかにアニメーションします。

ただLightBox風のJSを作る場合に、レイヤーを貼った上にボックスを表示してその表示方法がアニメーションのときにはちょっと注意が必要です。

input type="button"を押したらボックスを表示するとして、レイヤーが表示され始めているのにレイヤーの後ろにいるbuttonを押せてしまう場合があります。

つまりレイヤーが表示されたタイミングでbuttonのonclickをfunction(){}(つまり空)にしてやるとか、それ以外でフラグを使ってすでに押されていることを把握する必要があります。
(※これは画像ボタンにすることで解消されるかも?未検証)

Safari3.1

完璧なブラウザです。

特にアニメーションに限っては文句の付けようがない感じです。
Safariの欠点は、Safariでは画像のloadが終わっていないとwidth、heightがうまく取得できないでも紹介しましたが、jQueryのreadyではDOM構築が終わっていない場合があるので、アニメーションさせたい対象のエレメントの幅を取得したい場合はonloadを待つほうが無難かもしれません。

Google Chrome

Safariと同じWebkitベースのブラウザなので、同じくキレイです。

ただ、ちょっと未確認なんですがJSファイルをBOMありのUTF-8で保存した場合に、うまくJSファイルを読み込んでくれなかったです。

他のブラウザでは問題なかったのですが、Google Chromeだけで発生しました。
対応としては、BOMなしのUTF-8Nとかで保存しました。
う~ん。

Netscape7

アニメーションはFirefox2.0よりは滑らかに感じますが、やはりちょっと微妙です。

各ライブラリがNetspaceに対応していないのもあり、opacityの透過などは自前で容易する必要もあったりします。
一応Netscapeではfloatしているブロックにrelativeをかけても効かないでちょっとした欠点も載せているので参考にしてください。

これ以外にアニメーションと関係ないですが、CSSで
background: url(/hogehoge.gif) no-repeat left 7px;
みたいにピクセル単位で座標を指定する場合がありますが、これにはNetscapeは対応していません。
いろいろ試してはみたのですが、ダメでした。
なので、
background: url(/hogehoge.gif) no-repeat left center;
などで対応。

まとめ

全ブラウザで同じように見せるスタイルシートも大変な作業ですが、JavaScriptを使ったアニメーションもブラウザの個性に対応しないといけないので、まだまだクロスブラウザ対応は必要そうですね。

Ajaxのオブジェクト(XMLHttpRequest or Msxml2.XMLHTTP)や基本的なDOM操作はライブラリが吸収してくれますが、アニメーションに限ってはどのスタイルを使ってアニメーションをするかは自分で決めなきゃいけないので、これからいろいろ調べていきたいと思います。

とはいってもjQueryのanimateメソッドにはすっごく助けられていますがw

■参考記事
jQueryのanimateメソッドの使い方
JavaScriptでアニメーション(animate)するときに気をつけたいこと

Netscapeではfloatしているブロックにrelativeをかけても効かない

ネスケのクロスブラウザ対応なので、あんまり必要はないかもしれないですが、
一応こんな現象を発見したのでメモメモ。

以下のように外枠のブロックに「float: right;」と「position: relative;」が掛かっている状態で、
中にいるブロックに「position: absolute;」で絶対配置にしています。

こうゆう例はちょっと珍しいですが、中にいるブロックが複数あってz-indexで切り替えるときとか
こんな感じかと思います。


んで、上の例だとネスケではrelativeが効かず、画面の左端に中のブロックが移動してしまいます。

これを解消するには「float」と「position」を別々のブロックにしてあげるとうまくいきます。

解決策

何かと何かを一緒のブロックに指定するとうまくいかないケースはIEだけかと思っていましたが、
以外にもネスケでこうゆうパターンがありました。

参考までに!

onloadを待たずに特定のエレメントに処理を実行する方法

ちょっとonloadを待たずに処理するのはどうやろう・・・みたいな疑問が沸いたのでメモメモ。

onloadイベントはwindowオブジェクトやimgタグ、scriptタグなど特定のものにしか存在しないので、擬似的に対象エレメントのDOM構築が終わったかどうかの判定ができません。
onload

なのでタイマーを使ってエレメントが取得できるまで繰り返し、その後に処理を実行するという方法ならDOM構築完了時に処理が実行できそうです。

たとえば上記のようなエレメントがあって、ここからid="hoge"のinnerHTMLをonloadイベントを待たずに取得したい場合は
以下のように書く感じです。

特定エレメントのidプロパティが取得できたらDOM構築が完了と考えていますが、もしかしたらこれだけだと判定としては弱いかもしれません。
ここは要調査!

画面の高さが結構ある画面なんかで画面初期でselectboxをdisabledにしたい~というときにonloadを待っているとかなり時間が経った後にdisabledになるので、こうゆう方法もありかもしれません。
DomContentLoadedでもそこそこ時間がかかるはずっ。

※divタグ自身にonloadがあったらな~。

jQuery Pluginの書き方

※10/14 もう少し詳しく書いてみる!

jQueryのプラグインなんかを書き始めると、どうゆう風に記述するかいろいろ人によって違うのでちょいとまとめてみました。
おそらくこれ以外にもありそうですが、比較的メジャーな感じで並べています。

jQueryには
  1. ①$("#hoge")で取得するオブジェクト
  2. ②jQueryオブジェクトそのもの

と2つのオブジェクトが存在します。
違いは①のほうは「$("#hoge").hogehoge();」という感じで書くことができ、②のほうは「jQuery.hogehoge();」とちょっとしたユーティリティのように書けます。
メソッドが実行されるタイミングで対象のエレメントが特定されてて欲しいなら①、そうでないなら②みたいにボクは使っています。

これを踏まえて以下のコードはjQueryオブジェクトにそのまま追加するパターンとして紹介しています。
もし①で使えるように追加するなら「$.fn.hoge」というようにfnを途中に追加してください。

一般的な書き方

よく見るコードはこの書き方かと思います。
関数の中では$で記述できるので比較的楽です。

ちょっと普通な書き方

これは1番目とあんまり大差はないですが、これも$で書けるのでまぁ楽チン!

jQueryオブジェクトをそのまま使う書き方

これは毎回jQueryドットと書かないといけないので、ちょっと面倒。
やっぱり1番目のほうがスマートですかね。

関数スコープに閉じ込めない書き方(これは良くない)

う~ん、これはjQueryっぽさがなくなっちゃうし、関数の外で書いた変数はスコープグローバルになっちゃうし・・・
バッドノウハウですねw


あと肝心なもう一個を記述し忘れてましたw

extendを使う書き方


以下jQueryの解説スライド。
こうゆうのをちょっと覗いてみるのも面白いですよ!

UTF-7でスクリプトを実行させるXSSについて

IEでUTF-7なスクリプトをiframeの中に表示するとXSSが発生するメモです。
あんまりこの話には詳しくないので、今後の調査材料として残しときます。
(※一応悪用厳禁であります!)

iframe内のエンコードが正しく指定されていない場合は、そのiframeの親にあたる部分のエンコードが自動的に適用されるというIEのバグがあるみたい。
今回はそれのちょこっとした検証!

1番初めに呼ばれるhtml(①.html)

iframe内で呼ばれるGetメソッド

結果

doGetメソッド内でエンコードを正しく設定せずにレスポンスしているため、IEでalertが表示される。

その他の実験まとめ

  1. 「①.html」ではなくiframeのパスを直接呼んだ場合はscriptは実行されない
  2. 「①.html」にmetaタグを正しく指定すればscriptは実行されない
    <meta http-equiv='content-type' content='text/html;charset=utf-8'>
    ただしutf-7を指定した場合はscriptは実行される(まぁそうだろうな)
    <meta http-equiv='content-type' content='text/html;charset=utf-7'>
  3. サーバー側でエンコード指定してもIEが解釈できないエンコードの場合はscript発生
    arg1.setContentType("text/html");
    arg1.setCharacterEncoding("utf8");	//正しくはutf-8
    
  4. 当たり前だがiframe内のhtmlに正しくmetaタグを指定すればscriptは実行されない

このお話はなかなか奥が深くてむずかしいですね。
とにかくIEに依存した Webアプリケーション セキュリティのプレゼン資料を見て勉強するしかなかそうです!


■参考にさせていた資料
IEに依存した Webアプリケーション セキュリティ
そろそろ UTF-7 について一言いっとくか - 葉っぱ日記
まだまだあるクロスサイト・スクリプティング攻撃法:ITpro
36. UTF-7とクロスサイト・スクリプティング:ITpro

(function(){})()の代わりにnew function(){}って方法もあるよ

だいたいは①の方法で即時実行な無名関数を作ると思うんですが、②みたいに書くこともできる。
でもボクはやっぱり①の書き方のほうが好きだな〜。

ただし、②の使い方にはちょっと気をつけないといけないです。
というのも②はfunctionをnewしちゃっているので、この関数はコンストラクタになってしまうこと。
なので以下のようにその関数が属するオブジェクトが変化してしまします。

もうちょい分かりやすく書くと以下の感じ。

func2のほうはnewした段階でコンストラクタが呼び出されるので、thisが代入先のobjに切り替わる。

ということでやはりnew function(){}よりも(function(){})()のほうが無難そうですねw
jQueryなんかもコード全体を(function(){})()で囲って、スコープを関数内に閉じ込めたりしてるし。(理由になってない!)

canvasを使って波紋が広がるripple.js作りました

ripple

canvas使って何かしたいな〜と思っていたら、波紋を描いたらちょっと面白いかもと思ってこんなJavaScript作ってみました。
あんまり深いこと考えてないですw

マウスの移動に波紋が付いてきます。
またクリックすると少し大きい波紋が広がります。

一応コードは以下の感じ。
canvasを使って丸を描いてます。(すごいシンプルっ!w)

またイベントのセットは以下のようにmousemoveclickに割り当ててます。
すいません、今手元にIEがないのでIEのチェックだけ出来ていないです。多分以下のコードで動くような〜。

Eventが発生するたびにマウスの座標をRippleクラスに渡しています。その後drawメソッドで描画しています。

とりあえず触ってみてください。
ripple.jsを触ってみる

ちょっと気に入っているのはこういったアニメーションするときに少し描画を遅らせるとそれっぽくなる気がします。
なので、マウスを移動したときに少し遅れて波紋が付いてくると思います。
こうゆうの結構好きです。

ソースは以下からダウンロードできます。
ripple.js


他にもこんなん作ってます。どうぞよろピク。
キングボンビーがサイトを侵略する?jQuery Plugin - kingbonbi.js作りました
なんかものが落ちるjQuery Plugin - JDropper作りました

Chromeのユーザーエージェント

一応メモ。
Webkitやね〜。

Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US) AppleWebKit/525.13 (KHTML, like Gecko) Chrome/0.X.Y.Z Safari/525.13

[via]
CyberAgent SEO Information

WebkitのDOMContentLoadedはDOM構築が完了していないかもしれない

Safari3.1でDOM構築が終わったタイミングでイベントを登録していたのですが、うまくいかなかったときのお話です。
jQueryを使っていたので自動的にDOMContentLoadedイベントに登録されると思っているのですが、これがどうもDOM構築が終わっていないんじゃないかと。

それが判明したのが、画像をスライドするパーツを製作していたときにスライド対象のdivタグのwidthを取得していて、このwidthがなぜかSafari3.1だと小さく取得されました。

以下にその例を載せて起きます。

SafariのDOMContentLoadedで失敗したパターン

画像がたくさん並んだボックスを左や右へスライドさせるときに、何枚あるか分からなかったので画像が入っているボックスのwidthを取得して計算をしていました。
以下にサンプルのHTMLを載せています。

このページの全体の高さは2500pxほどあります。ちょっと縦長なページ。
わけあってdivが2階層いますが、スライドさせる対象のエレメントはulタグになります。
このulのmargin-leftやmargin-rightを変更することによって画像がスライドしているように見せる感じで作っていました。

んで画面のDOM構築が終わった段階で、ulタグの幅を取得しようとしたのですが、なぜかSafari3.1でだけwidthが少なかったのです。
たとえばFirefox3では1000pxあったのに、Safari3.1では650pxとか。
かなり中途半端なwidthが取れていたので、これはもしやDOM構築終わってないんじゃ?
と思ってwindow.onloadにfunctionをセットしてみたところ・・・


「Safari3.1でもwidthが1000pxで取得できました。が~~~ん」

jQueryのreadyの中身について

久々にjQueryのreadyの部分を追ってみました。
bindReadyというメソッドが2329行目あたりにあります。
その中に以下の記述があるのですが、これは「webkit nightlies currently support this event」とコメントされているとおりSafari3.1ではDOMContentLoadedがあるのでif文に入ります。
参考リンク:Changeset 26101 -- WebKit -- Trac

そしてこのDOMContentLoadedを登録しつつ、その先に進みます。
2366行目あたり。

ここでSafariの場合に2つの方法を使ってDOMContentがLoadedになったかを確認しています

まずdocument.redayStateがloadedかcompleteになるまで自分自身の関数をループします。
ここのチェックが終わったらstyleタグとlinkタグの合計数とdocument.stylesheets.lengthが一致するまで繰り返します。

これら2つの条件をクリアしたらやっとDOMContentがLoadedになった状態とみなすようです。
なかなか複雑ですねw

ここでちょっと気になるのですが、Safari3.1では「DOMContentLoaded」がありますが、その後の「if ( jQuery.browser.safari ) {」にも入ってしまうのです。
なので2重のほうほうでDOM構築を待つ感じになっています。どっちのほうが速いの?w

ちょろっと簡単にテストしてみました

上記のコードを実行した場合の挙動が少しへんでした。
まずDOMContentLoadedでjQuery.readyが登録され、その後のSafariの分岐でdocument.readyStateの状態を監視します。
するとdocument.readyStateのif文には約1回くらいしか入らず、その下にあるif文には一切入りませんでした。

順番にしてみました。

  1. DOMContentLoadedにjQuery.readyを登録
  2. Safariの場合にdocument.readyStateを監視
  3. DOMContentLoadedイベント発生でjQuery.isReadyがtrueになる
  4. document.readyStateを監視しているがjQuery.isReadyがtrueなのでループを抜ける
  5. だからdocument.stylesheetsのlengthチェックが走らない

う~~~ん・・・
だとするとSafariのDOMContentLoadedのほうがjQueryのDOM構築待ちより速いということでしょうか。
速い故にまだ構築し終わってない?w
まさかね!

まとめ

かなりイレギュラーなパターンだと思いますが、Safariでこういう現象があったのは確かです。
なのでwindow.onloadを待つか、documentのDOMContentLoadedを待つかはテストしながら判断したほうがよいかもしれません。

Firefox3.0やIE7、IE6では特に問題がなかったです。
SafariのDOM構築って少しくせがあるので、そこが悩みどころですね。
レンダリング超速いですが・・・

JavaScriptで単体テストをするならQUnitはいかが?

「JavaScriptのテストってわざわざXUnit系を使ってまでする必要はない!」
みたいな意見は多々あるのですが、ライブラリなどを作っているときには非常に便利だったりします。
ちょこっとした修正がどの程度影響があるか分からないときに、テスト用のコードをしっかり書いてあればそれを実行するだけですんでしまいますからね。

そんで最近になって
JavaScript--単体テスト環境の選択肢 - builder by ZDNet Japan
という記事を見てて、「あれ?Qunitがないぞ!」と思ったので簡単に使い方を書いてみたいと思います。

上記リンクの記事ではJsUnitRhinoUnitのことが書かれていますが、これらはJavaありきというかANTありきなので、ちょろっとテストコードを書くというスタンスにはなかなか難しいと感じています。
ただJsUnitは全ブラウザを登録しておけば、いっきにクロスブラウザのテストを実行してくれるので便利といえば便利なんですけどね。

その点QUnitはjQuery用のテスティングフレームワークなので、コード量も少なく簡単にテストコードを書いていけます。
(少しだけjQueryに関する知識が必要になってきちゃうのはご愛嬌)

jQueryを使ったテスティングフレームワークですが、別に自作のライブラリのテストももちろんできますので、開発で使っているライブラリをテストすることができます。

使えるメソッドいろいろ

QUnit - jQuery JavaScript LibraryのAPI documentationのところに使い方が書かれていますので、ここではよく使いそうなメソッドだけを説明したいと思います。

test( name, test )

nameにはテスト名、testには実行したいテストコードを匿名関数で記述します。

module( name )

nameにはテストしたい単位を渡します。これはテストをしているときの目印になります。
たとえばレイヤーを操作するテストをしたい場合に

としておくと、テスト結果画面で
「レイヤー表示テスト module: レイヤーの枠を表示する (0, 1, 1)」

みたいにmoduleの手前にプレフィックスが表示されます。

ok( state, message )

stateにはfalseとtrueを指定できます。
falseの場合にはNG、trueの場合にはOKとなります。
これは帰ってきた値がtrueかfalseか、または通過したかしないかなどの判定に使えそうです。

messageは表示したい文字列を渡します。

equals( actual, expected, message )

これはよく使うやつですね。
actualとexpectedの値が同じ場合にOKとなります。

messageは表示したい文字列を渡します。


すぐに使いそうなのをご紹介しましたが、もっと詳しく知りたい場合にはjQueryのテスティングフレームワークQUnit (でぃべろっぱーず・さいど)をごらんください。
「提供されているメソッド」に詳しく書かれています。

QUnitのダウンロード

QUnit - jQuery JavaScript LibraryのUsing QUnitのところにjsとcssのリンクがあるのでここからダウンロードできます。

ダウンロードするのが面倒というかたは次の「QUnitを使ってみる」に進んでください。

QUnitを使ってみる

以下がQUnit用のHTMLになります。
ここにテスト結果がどんどん表示される感じです。

もしQUnitをダウンロードされた方はtestsuite.cssとtestrunner.jsのパスを変更してください。

今回はテスト用のコードを「qunit.js」に、テスト対象のコードは「hogehoge.js」として話を進めていきます。

テストしたいコードは以下になります。

文字列を返してきているので、これはequalsでチェックできそうです。
なので、qunit.jsには

と記述してテストを実行してみました。
実行結果は以下の画面になります。

failedが0になっているので、バグはなさそうですね。
おそらく大体がこういったテストで十分だと思うのですが、もしHTMLエレメントを使ったテストの場合には少し工夫が必要です。
どっかのdivタグのinnerHTMLを書き換えたテスト、id指定で取得したエレメントのwidthのテストなどはどうしてもHTMLを必要とします。
次はHTMLエレメントに対してテストをする場合を解説してみたいと思います。

HTMLエレメントに対するQUnitテストコードを書いてみる

今回はHTMLエレメントを透過させるメソッドをテストコードを書いてみました。
初めに必要になるファイルを解説します。

  1. qunit.js - テストコードが記載されているファイル
  2. hogehoge.js - テスト対象のコードが記載されているファイル
  3. opacity.html - 透過のテストをするときに使うHTML

透過に関するテストって自動でできるの?と考える方がいらっしゃるかもしれませんが、これが以外とできるんですw

先ほど使ったQUnitテスト結果HTMLは、あくまでもテスト結果を表示するものなのでこれとは別にHTML(opacity.html)を用意します。

まずは透過させるコードです。

これのテストコードは以下になります。

ここからがちょっと新しいテストコードになります。
テストコードの中でtestwinというメソッドを呼んでいます。これは新しくウィンドウをPopupさせ、そのHTMLの描画が完成した瞬間にテストコードを実行してくれるすぐれものです。
つまりopacity.htmlを新しいウィンドウで開いてDOMの構築が完了したら透過のテストコードを実行してくれる感じです。

これはjQueryのoffset.jsの中を参考にしています。

続いてopacity.htmlの中身。

ここではjQueryのファイルとテスト対象のhogehoge.jsを読み込んでいます。
そしてscriptタグで「$(function(){});」を実行しています。
先ほどのテストコードでPopupした画面のDOM構築を待つと解説しましたが、これはつまりjQueryのjQuery.isReadyがtrueになるのを監視しているのです。
jQuery.isReadyはreadyというメソッドが呼ばれて初めて監視がスタートされるので、ここで$(function(){});を実行しているのです。
ちょいややこしいですねw

これでテストするためのコードがそろいましたので、実行してみたいと思います。

おお~Opacityのテストが実行されました。
$w("#opacity").setOpacity(0.2).getOpacity()で返ってきた結果が0.2なのでちゃんと透過機能がはたらいたようです。

まとめ

HTMLエレメントのテストで別のHTMLファイルを作らないといけないのはちょっと不便かもしれませんが、1回作ってしまえば後は何度でもテストが可能ですので、いつかきっとプログラマーを助けてくれると思います。

QUnitはJavaやANTなどが不要なため、完全に独立したテスティングフレームワークとして使えるので
「JSでテストコード書きたいけど敷居が高いな~」
という人にはもってこいなのではないでしょうか?

良く分からないこと

IE7.0でウィンドウを開いてテストするときに、まれにうまくいかないことがあります。
F5とかで再度テストをすれば大丈夫ですが、そうゆうときもあるようです。
Safari3.1やFirefox3では特に問題なかったです。
でもなぜIEだけ・・・

■関連リンク
Getting Started With jQuery QUnit for Client-Side Javascript Testing - Chad Myers' Blog
jQueryのテスティングフレームワークQUnit (でぃべろっぱーず・さいど)

onunloadイベントが拾えないパターン

onunload時に何か処理を実行して、その処理がとっても大切な場合は以下のパターンのときに
注意する必要があるかもしれないというメモ。

リンクを押して他の画面に遷移した場合

Firefox3.0
OK
IE6.0
OK
IE7.0
OK
Safari3.1
OK
Opera9.5
OK


F5を押した場合

Firefox3.0
OK
IE6.0
OK
IE7.0
OK
Safari3.1
OK
Opera9.5
NG


ブラウザを閉じた場合

Firefox3.0
OK
IE6.0
OK
IE7.0
OK
Safari3.1
NG
Opera9.5
NG

JavaScriptからOpacity(透過)を設定する方法

JavaScriptでアニメーションさせようとしたとき、意外と使うのがこの透過。
じょじょに透過させていくとか、見栄えもかっこよくボクは良く使います。

でも既存ライブラリを使った場合、Netscapeに対応していない場合が多いです。
jQueryPrototype.jsはそもそも対応ブラウザにNetscapeが含まれていないので当然といえば当然ですね。
それでもNetscape対応させたい場合のメソッドを作ってみました。
すんごい短いコードですw

一応ライブラリごとのOpcityの設定について書いておきます。

jQueryからOpacity

PrototypeからOpacity

自作メソッドからOpacity

3パターンのOpacity設定を使って、どのブラウザでも透過ができるようになっています。

JavaScriptやCSS、Railsなど使えそうなチートシートいろいろ

Cheat Sheets - Added Bytesで開発に役立ちそうなチートシートが公開されています。

PDFで落とすことができますが、PNGもあるのがありがたい。

チートシートもみやすく前にPrototype.jsのチートシート(ver1.5、1.6)で紹介したものを合わせてどこかに貼っておけばきっと開発を助けてくれるはず。


JavaScript Cheat Sheet


JavaScript Cheat Sheet - Cheat Sheets - Added Bytes

CSS Cheat Sheet


CSS Cheat Sheet (V2) - Cheat Sheets - Added Bytes

JavaScriptライブラリ毎のSelectorAPIの速度一覧

普段はPrototype.jsjQueryを使ってJavaScriptを書いているのですが、そこまで複雑なCSS SelectorAPIは使ったことがないのでこうゆう一覧、というか実際に実行して確認できるのはありがたい。

SlickSpeed Selectors Test

SlickSpeed Selectors Test

検証してくれるJavaScriptライブラリは以下のとおり。

  • DOMAssistant2.7.2
  • jQuery1.2.6
  • Prototype1.6.0.2
  • Mootools1.2
  • ExtJS Core2.2
  • Dojo1.1.1
  • YUI2.5.2

MacのSafari3.1で試してみたのですが、DOMAssistantというライブラリがおそるべき速さで実行できています。
もっとも遅かったのはYUIですが、Prototypeもそれに負けずに遅い感じでした。

jQueryはさすがですが、Extに負けているのがビックリ。

いろんなブラウザで試せばこれで一通りのベンチマークになりますね。
とはいっても複雑なCSS SelectorAPI書くより、idふるなり適当なclassを割り当てたほうが良さそうですねw

addEventListenerとattachEventでは実行される順番が違う

たとえばPrototype.jsを使っている場合、

こんな感じでイベントを登録することができる。
また同じオブジェクト(window)に対して同じイベント(load)を指定した場合は、追加として登録される。
なので上書きはされない。

こうゆう場合にIEとIE以外では挙動が違うので一応メモを残しておきます。

IEのattachEventの実行順序

一番最後に追加されたイベントから一番最初に追加されたイベントにさかのぼるように実行される。

なので上記のコードでは2→1

IE以外ののaddEventListenerの実行順序

一番最初に追加したイベントから一番最後に追加されたイベントを実行される。

なので上記のコードでは1→2

まとめ

初めPrototype.jsが何かしているのかと思ったのですが、とくにそれっぽい箇所がなく以下のように自作した関数でも再現したため、こうゆう挙動は一般的なんでしょうね。

一番最初に登録したイベントから実行されるのを望む場合はIEとIE以外で挙動が違うのでハマる危険性がありますね。

追記:
IEのイベント実行順序は不定? - inamenaiの日記でさらに実験をしていただきました。
attachEventは単純に逆順になるわけではなくランダムだそうですw
でも何度か実行しても同じ順序になるようなので、何か法則でもあるんでしょうか・・・

CSSファイル内に他のCSSファイルをインクルードする方法

ひとつのCSSファイルを共通部分をあの画面とこの画面とかで共通で仕様したいがlinkタグを追加したくないとかに便利。

読み込むCSSは1つのファイルなのに、CSSファイルの中から別のCSSファイルをインクルードしてくれるので、2個のCSSファイルを読み込んでくれる。

index.html style.css include.css


あんまり使う機会はなさそうですねw

DOM Events - DOMAttrModifiedを使ってみる

イベントを登録されたオブジェクトの属性が変更された場合にfireされるイベント。
Document Object Model Events

あるHTMLオブジェクトの属性を監視するときに便利かもしれませんね。

setIntervalで監視しているのをこういったイベントに置き換えることによって、簡略化もできるし。
でもFirefox限定・・・

DOM Events - MDC

DOMとJavaScriptについて

DOM(Document Object Model)とは、HTML文書およびXML文書のためのAPIである。」
というのがDOMの説明に多いのだが、一体何がDOMで何がDOMではないのかを判断するのがちょっぴり難しい。

JavaScriptをコーディングしていて、「あ~この部分はDOMだな」とか「う~ん、ここはDOMではなくJavaScriptだな」とかを明確に判断する必要はないんだけれど、分かればもっと楽しくなるんじゃないかな。

なのでDOMで遊ぶ際に必要な知識なんかを以下にまとめてみました。
既知の情報も多々ありますが、個人的なメモなのでご了承ください。

DOMとは?

HTML(XML)のようなタグ構造を持つ文書に対して、あたかもオブジェクトのようにアクセスするためのAPIです。 HTMLはタグという文書構造になっているので、例えば「
」のようにidにhogeという文字を持つdivタグにアクセスしたいとしたとき、その方法を提供してくれるのがDOMの機能です。 document.getElementById - MDC

文書の構造なのにJavaScriptからオブジェクトのようにアクセスできるのはとっても大切で、表示している文字列を書き換えたり背景色を変更したり、アニメーションさせたりといろんなことができてとっても楽しいのです。

そういった便利な関数やプロパティはオブジェクトとして提供されDOMインターフェースというものを通じてボクらはアクセスすることができます。

たとえば以下のようにtableタグを作るためにdocumentオブジェクトが持つcreateElementメソッドを使ったとしましょう。
この場合var宣言で定義されたobjには何が入っているのでしょうか?

JavaScriptでいうところのオブジェクトなのには変わりないのですが、new Object()とした場合と今回のようにcreateElementした場合ではオブジェクトの中身が全然違います。
「HTMLTableElementというDOMインターフェースを実装したtableオブジェクト」というのがobjに入っているオブジェクトの正体ですね。
(なんだか長ったらしいですが・・・w)

createElementでtableオブジェクトを作った場合にはinsertRowというメソッドを持ちますが、new Object()ではそのようなメソッドは持っていません。
これはHTMLTableElementインターフェースを実装しているかそうでないかの違いです。
HTMLTableElement (Common DOM API)

DOMって他の言語でも使えるの?

DOMの機能はPerl・Java・ActiveX・Pythonなどで提供されているようです。
確かにXMLを読み込むような処理の場合にDOMが使えれば簡単にアクセスできますもんね。

PythonのDOMを使った例

# Python DOM example
import xml.dom.minidom as m
doc = m.parse("C:\\Projects\\Py\\chap1.xml");
doc.nodeName # DOM property of document object;
p_list = doc.getElementsByTagName("para");


via: 導入編 - MDC

JavaのDOMを使った例

初めにXMLの読み込み処理がありますが、それ以降はほとんどJavaScriptで使ったものと同じですね。

このようにDOMは他の言語でも提供されているありがた~いオブジェクトなわけです。
これもDOMというものを中立に考えて機能を実装してくれているからなのでしょう。

何がDOMで何がJavaScript?

ここが本題といったところでしょうか。
どこがDOM?みたいに疑問を持つことは普段のコーディングにあんまり影響はしませんが、たとえばwindow.alert()ってDOMなの?そうじゃないの?みたいに少し突っ込んでみると興味が沸いてくると思います。

alert() は引数の文字列が入ったダイアログをポップアップする DOM のメソッドです。


via: The DOM and JavaScript - MDC

とmozillaで解説されているので、これは間違いなくDOMの機能でしょう!

では以下でDOMの場所を特定して解説してみたいと思います。
なおThe DOM and JavaScript - MDCのDOM と JavaScript - 何が何をしているのか?を参考にしています。というかほぼ一緒!


サンプルコードたったこれだけです!w
これだけあれば十分です。

var obj =

ここはobjというJavaScriptの変数を作成しています。

document.getElementsByTagName("div");

Documentインターフェースを実装しているdocumentオブジェクトのgetElementsByTagNameメソッドを使ってHTMLページの順番でdivタグを取得しています。
ここで取得されるオブジェクトはNodeListインターフェースを実装している配列になります。
なのでlengthというプロパティを持ってはいますが、これはJavaScriptの配列のlengthとは違います。
NodeListインターフェースが提供しているlengthとJavaScriptが提供している配列という違いですね。

alert(

DOMの機能を使ってダイアログを表示します。
(今までにこのメソッドを何度使ったことか・・・最近はconsole.logになりつつありますが)

obj.item(0).id);

ここはちょっぴり複雑ですね。
まずobjにはNodeListインターフェースを実装した配列が入っています、そしてその一つ一つにはHTMLDivElementインターフェースを実装したオブジェクトが入っています。
NodeListインターフェースにはitemというメソッドがあり、引数に数値を指定することでdivオブジェクトを取得することができます。

そして取得したdivオブジェクトが持つidというプロパティにアクセスしていますね。
idというプロパティはElementインターフェースが提供しているプロパティです。
ということはHTMLDivElementインターフェースとElementインターフェースを実装しているということになります。
(2個も実装しているなんてなんて贅沢なっ!)

基本的なclassName、id、innerHTML、styleなどは確かにどのHTMLオブジェクトでもアクセスできるので一元的にElementインターフェースで実装しているんですね。
ほほぅ。
element - MDC

たった2行のJavaScriptを見てみましたが、こんなにもいろんな実装がされているなんて!といった感じでしょうか。
先のコードでDOMじゃない部分といえば、変数宣言のvar obj部分と;セミコロンくらいです。
それ以外が全部DOMで提供された機能だったというわけです。
DOM様様ですねw

まとめ

なんとなくDOMについてまとめておきたかったので今回の記事を書きましたが、結構ボリューム感がありました。
とはいってもmozillaのサイトに行けば、JavaScriptの仕様はたいてい記載されていますし、今は詳しく書かれた本もたくさん発売されています。
勉強するにはもってこいな時代ですね。
6年くらい前はまだAjaxもそんなに普及されていなくて、そもそもAjaxという言葉はなかったからずうっと「非同期」なんて呼んでいたりしました。
その当時はwindow.alertはDOMの機能だってことは、どこにも書いてなくて先輩とかに聞いて回ったのを覚えています。

なんかものが落ちるjQuery Plugin - JDropper作りましたで作ったオモロ~なプラグインもDOMの機能なしには語れないのです。

DOMを学びやすいJavaScript解説本

JavaScript 第5版
JavaScript 第5版
posted with amazlet at 08.09.02
David Flanagan
オライリー・ジャパン
売り上げランキング: 7060

やっぱりサイ本はかかせないです。
この本は重要なところを太字とかにあんまりしてくれていないので文章を読む感じで学習するのが得意な人に向いているんじゃないでしょうか。

Head First JavaScript 頭とからだで覚えるJavaScriptの基本
Michael Morrison
オライリージャパン
売り上げランキング: 4564

この本最近買ったのですが、アツいですw
イラストばんばん使いまくりで、クロスワードとかも途中にあって、学習というより遊びながらな印象があります。

まるごとJavaScript & Ajax ! Vol.1
天野 仁史 舘野 祐一 川崎 有亮 arton 田中 孝太郎 国分 裕 山本 有悟 海野 裕也 nanto_vi
インプレスジャパン
売り上げランキング: 125084

かゆいところまで突っ込んで解説されているので、かなりな良本です。
雑誌感覚なので、気軽に読めるのもいいですね。


■関連リンク
W3C Document Object Model
Gecko DOM Reference - MDC
org.w3c.dom (Java 2 Platform SE 5.0)

Arrayをforinするより普通にfor文で回すほうが速い

Arrayのlengthはいったん変数に格納してからループしたほうが速いに引き続きベンチマーク。

そういえば配列をforinで回したことがあんまりなかったので、普通のfor文とどっちが速いのかな~という疑問が沸いたので試してみた。

配列をforinで実行した場合

Firefox3.0
481ms
IE6.0
3234ms
IE7.0
219ms
Safari3.1
219ms
Opera9.5
234ms

配列を普通のfor文「for (var i = 0; i < a.length; i++)」で実行した場合

Firefox3.0
7ms
IE6.0
32ms
IE7.0
16ms
Safari3.1
16ms
Opera9.5
31ms


この結果でびっくりしたのが、forinで回した場合のIE6.0の遅さ
じゃっかんブラウザも固まりかけていました。

配列に対して以下のように3つしか値が入っていないのに、lengthが1001になる場合にはforinのほうが有効かもしれませんが、そうゆう使い方はあんまり配列ではしないのでやっぱり普通にfor文で回したほうがよさそうですね。

さらにlen=arr.lengthのように一旦lengthを退避すればなお良いということかな。

■関連リンク
JavaScriptの配列をも~っと深く理解する:lengthの不思議な動作 - page2 - builder by ZDNet Japan

Arrayのlengthはいったん変数に格納してからループしたほうが速い

既出な内容ではあるが、一応メモとして残しとく。

配列を走査するときに、配列のlengthを一旦変数に格納したほうが速いんじゃないかという話。
実際試してみた。

コードは以下の感じでどのブラウザでも実行できるようにしました。

配列のlengthを退避せずに実行した場合

Firefox3.0
12ms
IE6.0
63ms
IE7.0
63ms
Safari3.1
31ms
Opera9.5
32ms

配列のlengthを退避して実行した場合

Firefox3.0
7ms
IE6.0
16ms
IE7.0
31ms
Safari3.1
16ms
Opera9.5
16ms


おお~、全然違うみたい。
とはいっても9万回以上ループした場合の結果なので、実際の開発でこれぐらいの差がでるかどうかは微妙ですが、塵も積もれば何たらってやつで意識しておけば処理の重いJavaScriptでもちょっとしたメリットはあるかもしれません。

■関連リンク
JavaScriptの配列をも~っと深く理解する:lengthの不思議な動作 - builder by ZDNet Japan
配列を for で回すときは length を何度も参照すると遅い - gan2 の Ruby 勉強日記

Webサイトの高速化 - styleはheadタグ内に書くと描画が速い

Webサイトの高速化 ルール5 CSSは上に! (Yahoo! developer netoworkより翻訳) | パフォーマンスチューニングblog | インターオフィスより

スタイルシートの読み込みは普通headタグ内で行いますが、ときとして後からHTMLに追記したスタイルがHTMLの下のほうにある場合があります。
(本当はちゃんと別ファイルとして作成しなきゃいけないのですが、直接書かれている場合があったり・・・)

こういったことをしてしまうと、画面の描画に影響を受けるということを以下の記事で知りました。
IEなどはスタイルが読み込み終わるのをじ~と待っていて、Firefoxは待たずにどんどん描画してしまうので、display:noneな要素も一瞬見えてしまうなどの問題があったりするみたいです。



スタイルシートを下のほうに配置すると、IEも含めて多くのブラウザにとって、徐々にページを表示することができなくなります。ブラウザは、スタイルが変更されてページ要素を再描画しないといけなくなるのを避けるために、ページを読み込み終わるまで描画をブロックします。そのため、ユーザは真っ白なページを見続けることになります。Firefoxは描画をブロックしません。そのためスタイルシートをロードし終わった時にページ要素を再描画する場合があります。その結果、the flash of unstyled content problem(スタイル適用前のコンテンツが一瞬見えてしまうこと)といった問題が発生する場合があります。


via: Webサイトの高速化 ルール5 CSSは上に! (Yahoo! developer netoworkより翻訳) | パフォーマンスチューニングblog | インターオフィス


ユーザビリティとして真っ白な画面が何秒か表示されているのは具合が悪いもんです。
たとえば昔、巨大なTableタグでHTMLを囲っているときがありました。
今みたいにdivタグでfloatされるのが流行る前ですね。
Tableタグはその中身がダウンロードし終わらないと描画が開始されないので、ブログとかのテンプレでこの方法を使っているとユーザーは5秒以上何もない画面を見たりしてました。

それとAjax関連で通信をしているあいだ、グルグル回るアニメーションgifとかで「今検索してますよ~」を通知して待っているあいだもユーザーを不安にさせないなんて方法も今となっては主流ですね。

ちょっとした工夫で描画が変わってくるのはなかなか実感がないですが、意識しているだけで全然違うんでしょう!

いやはや勉強になります。

キングボンビーがサイトを侵略する?jQuery Plugin - kingbonbi.js作りました

更新履歴

2008/08/23
- いろいろ調整しながらなので、動かなかったりご迷惑をお掛けいたします。とりあえず落ち着きました。
- ブログパーツ用のコードを変更しました。JSファイルの読み込みではなくアンカータグにしました。

kingbonbi
なんかものが落ちるjQuery Plugin - JDropper作りましたに引き続きオモロ〜なJavaScriptを作ってみました。

なんでキングボンビーを採用したのかよく分からないのですが、お風呂の中でなんか面白いことJavaScriptで出来ないかな〜と考えていたらキングボンビーに行きつきましたw
しかも名付けて「kingbonbi.js」!!
そのままです。

ブログパーツかBookmarkletとして公開いたします。
また今回もソースコードは公開いたしますので、何かの参考になれば幸いです。

続きからご覧ください。

Continue reading

jDropper.jsのブログパーツとBookmarklet

更新履歴

2008/08/23
- ブログパーツ用のコードを変更しました。JSファイルの読み込みではなくアンカータグにしました。

この前リリースしたなんかものが落ちるjQuery Plugin - JDropperのブログパーツとBookmarkletを用意してみました。

単になんかものが落ちるだけのjQuery Pluginですが、いろんなブログ上で実行してみると背景の配色が各々のブログで違うのでなんか面白かったですw

ブログパーツ用のコード

<a href="javascript:(function(){var%20s=document.createElement('scr'+'ipt');s.charset='UTF-8';s.language='javascr'+'ipt';s.type='text/javascr'+'ipt';var%20d=new%20Date;s.src='http://lab.hisasann.com/jdropper/js/bookmarklet.js?u='+escape(document.location.href)+'&d='+d.getMilliseconds();document.body.appendChild(s)})();"><img src='http://lab.hisasann.com/jdropper/img/jdropper2.png' style='border: 0px ;'/></a>

Bookmarklet用のリンク

以下のリンクをブラウザのお気に入りにドラッグしてください
jDropper

ご利用にあたって

本PluginはjQueryを使っておりますので、ブログパーツやBookmarkletを使った場合に画面の挙動がおかしいなどの現象がある場合にはご利用にならないようお願いいたします。

jQueryのheight()やwidth()はOpera9.5に対応していない気がする

jQueryは1.2からheightメソッドやwidthメソッドでdocumentwindowのサイズを取得することができるが、Opera9.5対応がされてないような気がしたのでメモメモ。

heightメソッドやwidthメソッドは本当に便利で以下のようにエレメントの幅や高さを簡単に取得することができる。

これはこれで重宝するメソッドではあるのですが、どうもOpera9.5でwindow(表示されている領域)の幅や高さを取得したときに思ったとおりにならなかった。

で、実際jQueryを見に行ってみた。

jQuery 1342行目

No~~~~~!
Operaの場合(jQuery.browser.opera)にdocument.body[ "client" + name ]で取得している。
このdocument.body[ "client" + name ]はおそらくOpera9.5未満のバージョンで有効なんじゃないかな?
今手元にその環境がないので確かめられないのだが、以下のとおり9.5からは
document.documentElement.clientWidthdocument.documentElement.clientHeightを使うべきだと思う。

Opera 9
標準
document.body.clientWidth
document.body.clientHeight


互換
document.body.clientWidth
document.body.clientHeight


Opera 9.5
標準
document.documentElement.clientWidth
document.documentElement.clientHeight


互換
document.body.clientWidth
document.body.clientHeight


via: ブラウザの表示領域のサイズを取得する方法。 - Enjoy*Study

ということでOperaでうまく取得できないので、自作!

jQueryのメソッドをさらにラップする形にしてみました。
これでいけるっしょ!
でもこれだと今度9.5にしか対応していないから、バージョンごとに分けないといけないのか。
面倒だな〜w

次のjQueryのバージョンで直るのかな?

Safariでは画像のloadが終わっていないとwidth、heightがうまく取得できない

IE6.0、IE7.0、Opera9.5、Firefox3.0ではちゃんと画像の幅や高さが表示されるのに、
Safariでは画像のwidth属性height属性をキチっと指定しないと「0」になってしまう。

今回はjQueryを使ってサンプルを紹介していきます。

たとえば以下の場合

そんなに普段画像の幅や高さを取得したりすることは少ないかもしれないが、
意外とハマるので気をつけたい。


そしてこれを回避するためには以下のように画像のonloadを待つ必要がある。

これでSafariでようやく画像の幅、高さが取得できるが、毎回onloadイベントをbindさせるのも面倒だし、
バインドできないシチュエーションなんかもあるかもしれない。

なので単純にimgタグの中にwidth属性とheight属性を必ず書くようにする。
これでSafariの場合でも問題なく幅、高さを取得できます。

実際のデザインのときはだいたいimgタグのwidth属性とheight属性は書いているけど、
書き忘れ時にこの現象に遭遇するでしょう。
こうゆうのって意外とハマりますよね。

なんかものが落ちるjQuery Plugin - JDropper作りました

更新履歴

2008/08/21
- easingの種類を増やしました
- id:pyangoroさんの指摘で名前を変更しましたw
- id:ぁゃιくない(*~Д~)さんのさんまの名探偵的なゲームだと面白いという意見によりちょいゲーム化
- duration(速度)をパラメータとして渡せるようにしました

jdropper

画像やHTML要素が雨のように降り注いだら面白いな〜と思ってこのjDropperを制作しました。
特にこれを使って何かが出来るわけではないですが、ブログパーツの一種として使っていただけたら幸いです。

続きからご覧ください。

Continue reading

Mac OS X 10.5にMT4をインストールしてみた

Perlの勉強としてPlaggerをおすすめされている方は多いと思いますが、せっかく普段MTを使っているのでローカルにMT4をインストールしてみました。

MT4をダウンロードする

以下のサイトからダウンロードし、解凍しときます。

Six Apart - Movable Type のライセンスと購入について

httpd.confの編集

Mac OS Xには「/Users/[ユーザ名]/Sites/」ディレクトリにhtmlファイルを置くと自動的にhttpでアクセスできるようになります。
まずはWeb共有で公開するためのフォルダでCGIが動くように設定します。

このディレクトリにある自分の名前のconfファイルを編集します。(httpd.confファイルではありません)
編集にあたって事前にコピーしてバックアップしておくことをオススメします。

[ユーザー名].confを開いて、

を以下のように編集します。

これでCGIが動く環境が整いました。

Web共有を有効にする

システム環境設定の「共有」を開きます。
そして以下のように「Web共有」にチェックを入れれば完了です。

51716709

MT4をサイトディレクトリに配置する

解凍したMT4フォルダをFinderからサイトディレクトリに配置しました。

あとは「http://localhost/~[ユーザー名]/mt4/」にアクセスすればMT4のindex.htmlが読み込まれます。
やった〜〜!

■関連リンク
Mac OS X 10.5 ( Leopard ) でCGIを使用する - sbs_tsの日記
の記事を大変参考にさせていただきました。

買った本

Head First JavaScript 頭とからだで覚えるJavaScriptの基本
Michael Morrison
オライリージャパン
売り上げランキング: 1352

いっけん筋肉増強をさせられるんじゃないかと思っちゃうジャケットですが、JavaScriptをイラスト付きで解説しているということで購入。
4200円だからすり切れるまで読みますw

Firefoxプラグインで入力補完が使えるCSSエディタ

Firefoxプラグインで入力補完が使えるCSSエディタ

ちょろっとCSSを書きたい人向けなFirefoxプラグインです。
入力補完機能があるので、「あのプロパティどうゆうスペルだっけかな?」というときに重宝しそうです。

MacのTextMateを使っている人にはまったくもって必要のないプラグインですが、それでもちょろっとCSSには向いていますね。

以下のサイトの「Click here to download and install DiavoloTest 0.6.」というリンクからダウンロードしました。

<Glazblog/>

Event.observeでセットするfunction内のthisについて

例えば以下のようにセットすることは多々あると思うのですが、

注意したいのは「this.id」としている部分。
ここのthisはもちろん"hoge"オブジェクトになっててほしいところなんですが、IEではwindowオブジェクトになってしまいます。
以下のサンプルではalert(this.id)でhogeが表示されてほしいところですが、windowIdが表示されます。

が~~ん!

これはPrototype.jsの中でattachEventを使ってイベントを登録しているのが原因かな~なんて思っています。
まぁIEでイベント登録するときはattachEvent使うしかないのですが・・・

ためしにEvent.observeの部分を自分で書いてみたのですが、やっぱりattachEventの部分が「windowId」になる。

さらっと使っていますが、「Event.element(e).id」を使って自分自身のオブジェクトを取得できるようです。
一応これで解決かと思いきや、まだダメなパターンがありそうです。

クリックされたエレメントの上位エレメントにイベントが登録されている場合

クリックされるアンカータグのひとつ上のエレメントにIDがふられて、そのエレメントにイベントが登録されているパターン。

この場合だとまずIEでthis.idはwindowオブジェクトだし、Event.element(e).idで取れてくるのはアンカータグのIDだし・・・
んもうっ。

結局のところ

なんか嫌だけど、こうなの?w

すんごい初歩的なところで悩んでいますが、jQuery使っているとこのあたりが非常にもどかしい。
というかもっといい方法がありそうだw

JavaScriptでアニメーション(animate)するときに気をつけたいこと

サンプルコードを書いていないんだけど、ちょっと基本的かつ意外とハマる問題かな~と思ったのでメモメモ。
とは言っても2点だけw

スライドするdivタグの中にはoverflow:autoなdivタグは入れないほうがいいかも

このシチュエーションは意外あると思う。
divタグ(div1)の中に複数のdivタグ(div2)が入っていて、外側のdiv1をアニメーションでスライドさせてdiv2の部分を切り替えるシチューエーションの場合、div2がoverflowをautoになっているとFirefoxチラチラする。
他のブラウザではこのチラチラ現象は起きないんだけど、どうしてもFirefoxで起きてしまう。
(IE6.0、IE7.0、Safari3.1、Opera9.5ではチラチラしない)

解決策

これを防ぐにはoverflowをhiddenとかにしてautoじゃない状態にする。

ちなみにjQueryでは、animate関数(3026行目の中でこのチェックをしているがアニメーションするdivタグの中にいるdivタグには適用されないので自分でhiddenにする必要がある。

アニメーションする前にhiddenにして、アニメーションが終わったらautoに戻す感じね。

スライドするときにmarginをマイナスとかにしてスライドするとIE6で重くなる場合がある

jFlowというスライド用のjQueryプラグインではmarginLeftmarginTopを使って対象エレメントの位置をずらしているんだけど、もしかするとIE6.0でめちゃくちゃ重くなる可能性がある。

たとえば画像がたくさん入っているdivタグが何枚もあって、そんなエレメントをmarginを使ってスライドする場合は結構厳しい。IE7.0ではすんなりスライドしてくれるんだけど、IE6.0だけカクカクしちゃう。
本来jQueryのanimateはブラウザ依存しないでキレイにアニメーションしてくれるんだけど、このmarginだけは特別なのかしら?

解決策

position:absoluteで位置をスライドするようにする。
とりあえずこれでIE6.0でもカクカクせずに、本来のサクサク感を出すことができる。

まとめ

全ブラウザで同じ感じでアニメーションさせるのは、たとえjQueryを使っていてもなかなか難しい・・・
日々精進でありますっ!

JavaScriptからfloatを取得するときはちょっとした工夫が必要

要素(エレメント)にfloatさせて左やら右やらに詰めて表示する場合に、スタイルから指定するのではなくJavaScriptから指定する場合は以下のように「styleFloat or cssFloat」というプロパティ名でアクセスする必要がある。

わざわざプロパティ名を分けないといけない理由は、以下のようにブラウザによってプロパティ名が違うから。

IEは'styleFloat',Firefox,Safariは'cssFloat',Operaはどちらも大丈夫です


via: prototype.jsを読み解く:第5回 Prototypeライブラリ(1290~1608行目)|gihyo.jp … 技術評論社

floatなんだからそのままfloatでもいいじゃないっ!プンプン。

ちなみにカレントスタイルの取得方法もブラウザによって違う。
なのでIE、Operaは「ele.currentStyle」を使って、
それ以外は「document.defaultView.getComputedStyle(ele, '') 」を使うように分岐している。

Prototype.jsやjQueryを使っているとこうゆうのはあんまり気がつかないが、独自ライブラリ製作では必須になってくるでしょうね。

■関連リンク
getComputedStyle について調べてたら深みにハマったのでメモ - IT戦記
prototype.jsを読み解く:第5回 Prototypeライブラリ(1290~1608行目)|gihyo.jp … 技術評論社

Seaser2を手軽に試すチュートリアル

前に試したはずなのにそのナレッジが手元になかったのでもう一回入門編を試してみました。

JDKのバージョンは「1.5.0_10」で、Eclipseは「3.2」です。

Seaser2のダウンロード

Seaser2のダウンロードは以下から「S2Container 2.4.26」をダウンロードしました。
Seasar2 - Downloads

Eclipseへのインポート

Eclipseのメニューから
「ファイル」 →「インポート」 →「一般」 →「既存プロジェクトをワークスペースへ」 →「次へ」
を選択していって、「アーカイブファイルの選択」で先ほどダウンロードした「S2.4.26.zip」を選択する。

後は次へでインポート開始!

ここから20分ぐらいかかっちゃいましたw
もっと必要なものだけで遊んでみたかったのですが、Seaser2のjarだけじゃどうせだめだろうと思って20分真剣に待ってみました。
(Springのほうもそうですが、aopalliance.jarが必要だのcommons-logging.jarが必要だとか言われのが面倒なので)

Mainクラスの作成

mainメソッドを持つクラスを作成していきます。

とりあえずこんな感じ。

インターフェースの作成

こんだけ。

インターフェースをインプルしたクラス作成

メッセージをコンソールに表示するだけのクラスです。

diconファイルの作成

ダイコン・・・

少し補足ですが、
①はコンポーネントを手動で登録していくバージョンです。
 複数のクラスをDIコンテナに登録する場合はここにすんごい量の記述が必要になります。
 (後のAOPで定義しているのでコメントアウトしています)

②ここはSpringでいうところのautowireと同じ感じですね。
 正規表現で記述すると自動で登録してくれます。これは便利です。
 (後のAOPで定義しているのでコメントアウトしています)

③ロギング用のインターセプターの定義です。
 これはSeaser2で用意してくれてるインターセプターのひとつのようです。

④traceInterceptorアスペクトをどのクラスにウィービング(織り込む)をするかの定義です。
 呼び出すメソッドにしています。

実行結果

ようやく実行ができる状態になったのでいざっ!
Main.javaのソース上で「右クリック」→「実行」→「Javaアプリケーション」。

おお~、でたでた。
しかもAOPでトレースを出すインターセプターを設定しておいたので、BEGINとENDが出力されています。

まとめ

多分これだけだとSeaser2の利点であるホットデプロイが体感できないですが、初めの一歩としてはいいでしょう。
ただ疑問点が1個出た。
diconファイルの「①個別登録」の部分でnameを指定しているが、これはあれかなセッターインジェクション用なんだろうか。
name=""にしても問題がなかったから、(Service) container.getComponent(Service.class)で取得するときは型で判断してる?

次はS2Strutsだな。

■関連リンク
@IT:The Seasar Projectの全貌を探る(2)
Seasar2 入門

jQueryがIEでもローカルファイルにAjaxでアクセスできる理由

前にJavaScriptでローカルファイルにアクセスする方法でPrototype.jsではIEでローカルファイルにアクセスできないが、jQueryだとうまくいくというエントリーを書きました。

んでいまいちなんでか分からなかったのでjQueryのAjax部分を見てみました。

jQueryで簡単にAjaxコード

まずはjQueryでAjaxを使う方法。

大体こんな感じです。すんごい簡単で相変わらずビックリします!

では内部へ・・・

jquery1.2.6.js(2733行目)

ここにあるonreadystatechange変数に秘密が隠されていました。

普通onreadystatechangeに関数をセットする場合は、IEではActiveXObjectのMicrosoft.XMLHTTPが持つonreadystatechangeにセットすると思いますが、なぜかここでは変数に格納しています。

一方prototype.jsでは

とMicrosoft.XMLHTTPが持つonreadystatechangeにセットしています。
ここが大きく違いますね。

jQueryのほうではonreadystatechangeにセットされた関数をsetIntervalを使って監視しています。
そしてreadyStateが「4 = complete」になったときに処理を開始するようにしているようです。

これによりローカルファイルにもアクセスが可能になっているようです。
でもなんでこれでローカルファイルにアクセスできるんでしょうw
すげっ

上記の部分をふまえてjQueryよりもうちょい簡単にしたバージョンを載せておきます。
参考程度にどうぞ。

jQueryのAjax部分の簡易版

これを見ていてひとつ気になったのが、jQueryではMicrosoft.XMLHTTPを使っていますが、
どうしてMsxml2.XMLHTTPは使っていないのでしょう。
確かMsxml2.XMLHTTPのほうがパフォーマンスが良かったような気が・・・
これも要調査ですな!

■関連リンク
XMLHttpRequest - MDC
The XMLHttpRequest Object
解説 : XMLHttpRequest

bean:writeのfilter属性をfalseにした場合の挙動を追う

Strutsを使ってサニタイジングをした文字列を画面に表示したい場合、
bean:writeタグのfilter属性falseにすれば可能だが、実際にどうゆうクラスが行っているかをちょっと確認してみた。

大体の使いかたは以下の感じだろう。

これで
「<span>hogehoge</span>」
という文字が画面にそのまま出力されるようになる。

これはXSS(クロスサイトスクリプティング)を防ぐ最も重要なことですが、とは言っても
Java側のどのクラスがそれをやっているのかは知らなかった。

今回はstruts-1.3.5を使っています。
では以下じゅんぐり追っていこう!

struts-bean.tld(941行目)

まずはtldファイルの中のwriteを定義している場所を探す。
そうするとタグクラスとしてorg.apache.struts.taglib.bean.WriteTagが指定されていた。

WriteTag.class(246行目)

ここは実際にbean:writeが呼ばれた場合に行う処理の部分。
さぁどこでサニタイジングしているのかな?

filterでif文を分けていたので、ここだ!
TagUtils.getInstance().filter(output)
この部分が怪しい。

TagUtils.class(563行目)

んで、TagUtilsの中に飛ぶとResponseUtilsクラスのfilterメソッドを呼んでいた。

ResponseUtils.class(80行目のメソッドの中)

ありましたw
お決まりの置換処理ですね。
一見強烈に便利なbean:writeですが、蓋を開ければ実にベーシックな処理をしているのが分かります。

普通にWebシステムなんかを作っているとこのbean:writeを多用しますが、
毎回この処理を経由しているわりには速いなと思いました。
まぁそんなもんなんですかね。

bean:write改めて便利ですね~!

■関連リンク
The Ja-Jakarta Site - The Ja-Jakarta Project: サブプロジェクト - Struts翻訳
WriteTag (Apache Struts API Documentation)

Windows環境にPerlをインストールする方法(ActivePerl)

今までWindows環境にPerlをインストールしたことがなかったのでメモメモ。
普段Mac OS Xなので初めから入っているしね。

ActivePerlのダウンロード

以下のサイトからMSI形式のファイルをダウンロードする。
途中名前・メアドの入力が促される。
ActiveState - Online Store, ActiveState ActivePerl Detail

ダウンロードしたバージョンは以下のとおり

ActivePerl 5.10.0.1003

ActivePerlのインストール

次へ次へで完了。
環境変数へperlのパスも自動で追加してくれるみたい。(便利!)

テストプログラムで実行してみる

おお~、ちゃんと「hoge」って出た!


この手のインストールって一癖も二癖もあるんだけど、ActivePerlに関してはあっさり終わりましたとさ。
さぁてPerlの勉強でもしてみようかな。

■関連リンク
ActivePerlのインストール方法 - Windowsでperlを使おう!

jQueryで関数の中の関数でthisを指定してもwindowオブジェクトにならない理由

単純にapply関数やcall関数でthisの対象となるオブジェクトを指定しているからですw

とは言ってもjQueryの内部ではthisを使いまくっていて、ちょっと読むだけだと分からないこともあるので少し具体的にどうやっているのかjQueryの中をのぞいてみましょう!

今回はjquery.jsの1.2.6を使用しています。
また関数やメソッドといった言葉は「関数」に統一しています。後々ややこしくなりそうだったので。

jQuery.fx.each関数の場合

例えばeachという関数では指定したエレメントに合致した全てのエレメントに対して第一引数の関数を実行します。
使い方は以下の感じで引数でfunctionを渡せます。
以後このコードをサンプルとして使用していきます。

そしてこのときのthisは、#hogeで指定したエレメントになるんです。
なのでidプロパティを表示させると「hoge」と表示されます。
ここが重要なポイントですね。普通に独自に作った関数だとwindowオブジェクトになっちゃいますから。


ではjQueryの内部に侵入してみましょう。

jQueryの138行目にeach関数がありますが、その中では他のeach関数を呼んでいるようです。

これはjQueryオブジェクトに直接追加されているeach関数ですね。
先ほどのeach関数はjQuery.fxに所属していますが、今回呼び出しているのはjQueryオブジェクトに所属しています。
なのでまったく別ものの関数になります。
(ちょいややこしいです!)

ではjQuery.eachのほうへ。(724行目

今回はeach関数にfunctionしか渡しておらず、args部分を渡していないので無視しちゃいましょう。
なので一番多きなif文のelseのほうを見ていきます。

lengthは指定したエレメントが1つあるのでundefinedにはなりません。
よってさらにelseのほうになります。

ついに来ました!

「callback.call( value, i, value )」

の部分が
「関数の中の関数内でthisを使用してもwindowオブジェクトにならない理由」
です。
call関数でオブジェクト(指定したエレメント)の縛りをかけているのでthisがwindowオブジェクトではなくエレメントになるのです。

なんだかゴッツイですねw

jQueryで説明をすると結構大変でした。
なのでもうちょい簡略的なクラスを~。

自作クラスでeachっぽいことを表示した場合

う~ん、ついついjQueryっぽく書いてしまいましたが、こんな感じでしょうか。
関数に対して自分はどのオブジェクトに所属しているかを指定するのは一般的なことですが、jQueryではそれを簡単にキレイに使っている部分がポイントだと思います。

まとめ

今回はeach関数を取り上げてみましたが、他にもanimate関数なんかでもこのマジックが使われています。
時間があればそっちも追ってみたいと思います。
(animateのほうはもっとガッツリと重いです!)

Prototype.jsのチートシート(ver1.5、1.6)

すごい今さらな気もしますが、Prototype.jsを使っている方はデスクの脇にでもコピーして置いておくと便利かもしれない。
または電車通勤時の勉強に?

Prototype.js 1.5のチートシート

prototype.js

Prototype 1.5.0 Cheat Sheet - Snook.ca

Prototype.js 1.6のチートシート

perfection kills » Blog Archive » Prototype 1.6.0.2 Cheat Sheet

[via]
phpspot開発日誌

Opera9.5に搭載されているDragonflyが便利な件

Opera9.5に搭載されているDragonflyが便利な件

ボクはもともとFirefoxとSafariをずうっと使っているので、開発でももちろんどっちかを頻繁に使っています。
Firefoxの場合はFirebugは必須ですし、Safariの場合も標準で搭載されている開発ツールを使っています。
どっちもconsole.logが使えるので便利ですしね。

そして最近になってOperaのバージョンが9.5に上がっていたのでいろいろ遊んでいたのですが、標準搭載のDragonfly開発ツールが結構いい感じに仕上がってました。
中身はFirebugと同等なのですが、今回のOperaのUIにとっても合っててサクサクしててこれなら

「Firefox + Firebug」 or 「Opera + Dragonfly」

といった感じで開発を進められそうです。
Webインスペクタはもちろんのこと、HTML階層構造も表示を変えられたりできて見やすくできます。

Opera9.5 Dragonflyのボク的な便利機能

  1. Firebug相当の機能が盛込まれてる
  2. Altデバッガでalt指定していない画像などを一発で探せる
  3. アウトライン機能で画面の構成を確認できる
  4. 目次機能でh1・h2・h3などのタグ構成を一発で把握できる
  5. グリモン不要でuser.jsが使える
  6. Firefox3同等でかなりレンダリング速度が速い
  7. console.log() = opera.postError();
  8. とにかくUIがメタリック調でかっこいいw

メニュー「表示」のスタイルから実行できる機能は以下のとおり。

FirefoxのWeb Developerアドオンを入れれば上記相当の機能は実現できますが、とはいえ初めから入っているのは魅力的。

これでいよいよ全ブラウザ?で開発することが可能な環境が整ってきましたね。
ちょうどFirebug Lite 1.2登場のおかげでブックマークレットからFirebugを呼び出せるようになったし。これでIEも怖くない!

以下からOpera9.5 + Dragonflyをダウンロード可能です。
Opera Dragonfly

■関連リンク
Opera Dragonfly 入門 (Japanese) - Opera Developer Community
プログラマが生産性を上げるためにoperaを使うべき11の理由 - labs blog

IEでposition:absoluteを使った場合margin-topが無視されてしまう

前にIEでfloatを使った場合margin-bottomが無視されてしまうでfloatしたときのmargin-bottomが無視される件を取り上げましたが、今回はfloatとか特に使用していないのですがmargin-topがIE6.0IE7.0で無視される場合がありました。

条件はposition:absoluteなdivタグ(div1)と普通のdivタグ(div2)が並んでいる場合に、div1のほうはdisplay:noneにしておいて、div2にはmargin-topを指定しておきます。
そしてボタンなどからdiv1をdisplay:blockにするとdiv2のmargin-topが無視されてしまうようです。

position:absoluteなんだからdiv2の上にはいないはずだし、いたとしてもdiv2のmargin-topが無視されるのは意味が分からないな~。
ちなみにIEだけでした、他にSafari3.1やOpera9.5、Firefoxなどで試してみましたがこんな現象はなかったです。

display:noneな画像はOperaでPostされない

イメージタグを使ってなんらかのWebサービスに値をPostしたい場合に、そのElementがdisplay:noneだとなぜかOperaだけPostされなかったです。
あんまりdisplay:noneにしなきゃいけないシチュエーションは少ないかもしれませんが、これもまたブラウザの仕様なんですかね。

サンプルHTMLはこんな感じです。

以下Postされるかされないかの一覧です。

IE6.0
Postされる
IE7.0
Postされる
Netscape7.1
Postされる
Safari3.1
Postされる
Firefox3.0
Postされる
Opera9.25
Postされない

ただOperaのバージョンが9.25なので、最新の9.5でどうなっているかは試していませんw

■追記
コメント欄にて教えていただきました。

どうやら9.5から改良が入り読み込むみたいです。

まず前提として、Operaではdisplay:noneな画像(直接指定されていなくても、親のdisplay:noneを継承していれば)は読み込みをしない(リクエストが発生しない)という特徴があります(おそらく表示の高速化のためでしょう)。そのため、以前のバージョンではonloadイベントが発生することもありませんでした。


対して、Opera9.5ではimgにonloadが記述されている場合はdisplayに関わらず読み込みを行うように修正されました。


via: Opera9.2から9.5でのJavaScript周りの変更点 - 0x集積蔵

IE用CSSHackのアンダースコアハックについて

IE6や7での表示がどうしてもうまくいかない場合にはアンダースコアハックを使って、うまいことやる場合がありますが、ちょろっとテスト用のコードを書いたときにハマることがあるのでメモメモ。

アンダースコアハックは以下のようにプロパティ名の前にアンダースコア「_」をつけるのですが、これはあくまでもDoctype宣言がない場合にうまくいく方法です。
これを表示すると100pxのほうが無視され200pxが有効になります。

なので以下のようにDoctype宣言を入れて確認とかをするとまったく、アンダースコアハックが機能しない。
普通Webサイト製作ではDoctype宣言はほぼ必須になっているので、こうなってくるとそもそもアンダースコアハックが使えないのでは?というのがボクの考え。

出来ればハックを使わないほうがかっちょいいんですが、どうしてもIE6や7に適用したい~~~!というシチュエーションでは「* html body」を使うようにしています。

他にもいろんなCSSハックがあるようですが、分からなくなっちゃうので使うのは上記のやつぐらいですね。

■関連リンク
Lucky bag::blog: IE7 を含むモダンブラウザ向けの CSS ハックまとめ

AS3で画面いっぱい(フルスクリーン)で表示させる方法

YouTubeなどを見ていると、画面いっぱいに開くためのボタンがありますが、
どうやっているんだろうと思って調べてみました。

stage.displayStateプロパティの値をfullScreenにするだけだそうです。

ただし

フルスクリーン表示の切り替えは、セキュリティの都合上ユーザーが意図せずに行われるべきではないという事で、必ずマウスイベント中か、キーボードイベント中に記述する必要があります。操作していないときにプロパティを変更しても何も起こりません。


via: FlashゲームPG講座 For AS3.0【Stage クラスについて】

となっているので、ボタンとかを作って試したほうがよいですね。

以下はコンボボックスを使った場合のサンプルコードです。

このとき

とHTMLのほうでフルスクリーンを許可するのをお忘れなく。

■関連リンク
Flashゲーム講座&ASサンプル集【Flash の画面表示について】
FlashゲームPG講座 For AS3.0【Stage クラスについて】
[ActionScript 3.0]フルスクリーン(stage.displayState) | moriBlog

ActionScript(AS3)からJavaScriptを呼ぶ方法(ExternalInterfaceクラス)

以外とハマったのでメモがてらに残しとく。
Flashを作っていくとどうしてもHTMLと連携してみたくなっちゃうのが心情で、じゃあどうやってやるの?というとネットにはそこそこ情報が載っているのですが、何かと難しい。(ボクだけかも)

使ってるツール

Adobe Flash CS3 Professional(Flash 9.0)

新規にFlashを作ってみる

  1. ファイル→新規から「Flashファイル(AS3.0)」を選び新しくflaファイルを作成する
  2. 適当に名前をつけて保存しとく
  3. 1フレーム目を選択しF9ボタンを押す
  4. 出てきたアクションフレームに以下のコードを記載する

この状態で一旦パブリッシュしとく。(Shift + F12)

これでHTMLファイルが作成されるので、今度はHTMLを編集する。

HTMLファイルを編集する

※注意 HTMLを編集した後にまたパブリッシュしちゃうと元に戻っちゃうので注意
 これなんかいい方法ないのかな?

objectタグとembedタグのallowScriptAccessパラメータをalwaysにする。
これをしないとローカルファイルにアクセスするときにエラーが出る。

こうならないように編集した後のHTMLは以下。

でもまだ先ほどと同じエラーは解消されない。

JavaScriptを編集する

IEでは画面がLoadしただんかいでFlashがアクティブにならない現象があるので、
それを回避するためのJavaScriptを容易されている場合がある。
今回使ったFlash CS3ではもれなく、そのJavaScriptがデフォルトで記載されているので
これを消去する。

scriptタグ内にAC_RunActiveContentに関する記述があるので、全部取り除いてみた。

後はFlashからコールしたい関数を容易するだけ!

これだけw

これでHTMLをブラウザで表示した際に「Hello!」と表示されればOK!
AC_RunActiveContentを外さないとうまくエラーが消えないのがハマってしまったが、
これも何か回避方法があるんだろうか・・・

補足

ローカルFlashファイルからローカルHTMLファイルにアクセスする(今回の場合)ときに
警告ダイアログが出る場合がある。
そのダイアログの設定ボタンからAdobeのページに行って、フラッシュのセキュリティを「常に許可」とかにしとくと次回からちゃんとFlashが動作するようだ。

■関連リンク
Adobe - デベロッパーセンター : 外部APIを使用したFlashとJavaScriptの接続

IE6でレイヤーを表示するとプルダウンが前面にきてしまう現象

lightBox系の実装をしている場合、画面全体を覆うレイヤー1枚とダイアログ用のレイヤー1枚を表示することがありますが、
このときに背景にプルダウンがあるとそのプルダウンを1番前面に来てしまう現象がIE6であります。
IE7ではこのバグが解消されていますが、まだまだIE6のシェアは高いのでサービスによってはこのバグを取りのぞかなけらばならない場合があります。

  • プルダウンメニューの上にレイヤーを重ねると、プルダウンが手前に表示されてしまう不具合が修正されていた。
  • via: PXT255; - Internet Explorer 7 ようやくリリース

    方法としては画面にあるすべてのプルダウンを「display:none」にしてやる方法と「iFrameを使う」方法があります。

    display:noneは結構力技でプルダウンの個数に速度が影響されるため、あんまりオススメできません。
    なのでiFrameで画面全体を覆ってしまう方法をご紹介します。

    以下サンプルソースです。
    IE6の場合のみに、iFrameを作成し透過させます。
    これで画面内にあるプルダウンが見えなくなるので、バグを防ぐことができるのです。


    なんかトリッキーですが、これぐらいやらないとlightBox系の実装が不十分になってしまうんですね。
    う~ん、IE6対応・・・果てしなくメンドクサイw

    ちなみにこのコードはjQueryを使ったThickBox 3.1を参考にしています。
    ありがとうございます!

    ■追記
    どうやらhttpsのサイトでこのiFrameの方法を使うとIE6で確認らしきダイアログが表示されてしまうようです。
    なのでプルダウンをdisplay:noneにする方法のほうが確かかもしれません。

    ■さらに追記
    ewbi.develops: IE, IFRAME, and HTTPS
    こちらでiFrameを使ったHTTPSサイト対応が書いてありました。

    src="javascript:false;"

    これを入れると大丈夫みたいです。ボクはまだ確認できてませんw

    RubyでJavaが書けるjRubyをインストールしてみた

    jRubyのダウンロード

    以下よりjRubyをダウンロード。
    jruby-1.1.3をダウンロードしました。
    Index of /jruby

    ちなみにRubyのバージョンは、1.8.6で、JDKのバージョンは1.5.0_10です。

    環境変数の設定

    以下の変数を追加しました。

    JRUBY_HOME
    C:\work\jruby-1.0
    PATH
    %JRUBY_HOME%\bin
    これでコマンドプロンプトから
    jruby -v
    と打ってバージョンが表示されればOKです。
    (一発目はちょっと時間が掛かりました。)

    jirbで遊んでみる

    Rubyにはチョロっとプログラムをチェックしたいときなんかに使う「irb」が搭載されていますが、
    それのjRuby版です。

    コマンドプロンプトから
    「jirb」を入力し、入力待ちになりましたら
    「p "hoge"」
    と打てばhogeが出力されます。

    でもこれだとただのRubyですので、
    「import 'java.lang.System'」
    とJavaのインポート文を入力してから
    「System.out.println('hogehoge')」
    とすればちゃんと文字が出力されるのが確認できます。おお~~~!

    jirbから抜けるには「exit」と入力すればOKです。

    実際にRubyファイルに書いてみる

    以下のようにhoge.rbファイルを作成しました。
    中身で面白い箇所は、System.out.printlnを呼び出しているところですね。


    でさらにimport文を使って名前空間を省略できるようにすると


    なんかRubyとJavaが混在しているので難しいですねw

    まとめ

    じょじょにRubyの人気が出てきて、Ruby on Railsでの開発も小規模ながら進んできていると思います。
    そんなRuby on RailsからJavaのAPIを呼び出したり、他の人が作ったJavaライブラリを使ったり出来るのはとっても面白いと感じました。

    ただ2個の言語が混ざっているので、超エンタープライズなシステムでは厳しいかな?と思いました。
    でもWebサービス開発とかでRailsとJavaAPIのマッシュアップみたいなことができたらなんか楽しそう。
    RailsからJDBCでRDBにアクセス!すっ、すごいっす。

    ■関連記事
    [Think IT] 第2回:JRubyでHello, World! (1/2)
    こちらの記事を大変参考にさせていただきました。

    jQueryで画面の中央に要素を表示する方法

    jQueryで画面の中央に要素を表示する方法 レイヤーを表示する場合なんかに有効な方法ですが、画面の中央にダイアログやボックスを表示する場合 jQueryを使うとかなり簡単に書けました。

    以下のコードはwindowオブジェクトをjQueryの引数に渡してwidthメソッドheightメソッドで取得しています。

    jQueryのwidthメソッド・heightメソッドを使う


    #hogeというのは中央に表示したい要素のidになります。
    animateでアニメーションさせるとちょっぴりかっこよくなりました。

    Firefox3とIE7で確認しましたが、ちゃんと真ん中に来てました!
    これは助かります。

    ちなみに画面全体(スクロールする部分も含む)の幅や高さを取得したい場合は

    とすると取得が可能です。

    jQueryを使わずに自前でやってみる

    クロスブラウザで泣きを見るパターンですが、画面の幅や高さを取得する方法は
    各ブラウザによってさまざまです。
    なのでレイヤー関連を扱う場合には以下のように、クロスブラウザ対応で取得する必要があります。

    う~ん、あんまり見やすいコードではないですが、jQueryを使えない縛りがある場合には
    こんな感じで書く必要がありますね。

    上記コードは
    • Firefox1.5~3
    • IE6.0
    • IE7.0
    • Netscape7.1
    • Opera9
    • Safari3.1

    などなどに対応している感じです。

    ■関連リンク
    ブラウザの表示領域のサイズを取得する方法。 - Enjoy*Study
    を参考にさせていただきました。
    どうもありがとうございます!

    Objectへの分割代入って面白い

    こんなことができるみたい。
    [via] 素人がプログラミングを勉強するブログ

    オブジェクトが持っているプロパティ名と同じ名前のハッシュIDを持つハッシュを作ると、いちいち何行もプロパティを抜き取る処理を書かなくてもよい。
    なので、自作したクラスとかで試してみるとこんな感じになる。

    さらにこう書いて、変数を省略することもできるみたい。

    なかなか興味深いですね。

    ライブラリ製作で使われているレトロなJavaScript関数10個

    Top 10 custom JavaScript functions of all time

    こちらの記事は2005年に書かれたものですが、久々にこういったJavaScript関数を見ると先駆者たちはすごいな~と関心させられます。

    たとえば、

    イベントを追加するaddEventメソッド

    ほんといまさらですが、よくできたメソッドだと思います。
    今では当たり前かもしれませんが、addEventListenerattachEventを使ってIEとIE以外を振り分けているのとか、なんかグッときちゃう。

    function addEvent(elm, evType, fn, useCapture) {
        if (elm.addEventListener) {
            elm.addEventListener(evType, fn, useCapture);
            return true;
        }
        else if (elm.attachEvent) {
            var r = elm.attachEvent('on' + evType, fn);
            return r;
        }
        else {
            elm['on' + evType] = fn;
        }
    }
    

    よくclass名からエレメントを特定しているけど、これってどうやってるの?という場合には以下、

    クラス名から取得できるgetElementsByClassメソッド

    結構レトロですが、HTMLタグが引数に設定されていない場合は全体から特定のclass名を持つエレメントを探していますね。
    う~ん、これはなかなか重そうだ。

    function getElementsByClass(searchClass, node, tag) {
        var classElements =  new Array();
        if (node == null )node = document;
        if (tag == null )tag = '*';
        var els = node.getElementsByTagName(tag);
        var elsLen = els.length;
        var pattern =  new RegExp('(^|\\\\s)' + searchClass + '(\\\\s|$)');
        for (i = 0, j = 0; i < elsLen; i++) {
            if (pattern.test(els[i].className)) {
                classElements[j] = els[i];
                j++;
            }
        }
        return classElements;
    }
    

    prototype.jsやjquery.jsを使っているとあんまり気にしないかもしれませんが、ちょっとのぞくとレトロなからくりだったり、関心させられるからくりだったりするのでたまに振り返るのは悪くないかもしれません。

    これ以外にも面白い関数が紹介されていますので、是非見てみてくださいな。

    Top 10 custom JavaScript functions of all time

    jQueryのanimateメソッドの使い方

    jQueryで作る Ajaxアプリケーション
    jQueryで作る Ajaxアプリケーションを読んでてanimateメソッドについて細かく書かれていたので遊んでみました。
    (本当はjQueryのソースを追ってたのですが、なんか難しくて挫折してたので本当に助かります!)

    前にjQueryのtoggleメソッドって気持ちいいでtoggleメソッドの使い方なんかを紹介しましたが、このメソッドも内部的にanimeteメソッドを呼んでいます。

    toggle : function (fn, fn2) {
        return jQuery.isFunction(fn) && jQuery.isFunction(fn2) ? this._toggle.apply(this, arguments) : fn ? this.animate( {
            height : "toggle", width : "toggle", opacity : "toggle";
        }
        , fn, fn2) : this.each(function () {
            jQuery(this)[jQuery(this).is(":hidden") ? "show" : "hide"]();
        }
        );
    }
    , 

    animeteメソッドのシグネチャー

    animeteメソッドのシグネチャーは

    こんな感じで、

    animate : function (prop, speed, easing, callback)

    いったい何ものかと言うと、

    prop
    CSSプロパティを連想配列でいっきに渡せます
    speed
    名前のとおりアニメーションのスピードです
    easing
    アニメーション方法を指定できます。プラグインなどを使う場合にはここの文字列を変更するみたいです。デフォルトでは"linear"が指定されています
    callback
    アニメーション完了時に呼び出したいコールバック関数を指定できます

    この4つのメソッドを渡すことによっていろいろなアニメーションをさせることができるのです。
    なんか意外と簡単そうです。

    Continue reading

    Operaが持つwindow.operaオブジェクトについて

    prototype.jsを眺めていたら出だしのところでブラウザ判定としてOperaの場合に、「!!window.opera」を書いてあったので試してみた。

    ブラウザがOperaかどうか判定する処理

    if (window.opera) {
        alert("Operaだね" + opera.version());
    }
    else {
        alert("Operaじゃないね");
    }
    

    versionという関数?があってこれにはOperaブラウザのバージョンが入っているみたい。
    ボクの環境ではOpera9.5が入っているので、alertには9.5と表示されました。

    SafariのconsoleオブジェクトといいOperaのoperaオブジェクトといい結構独自実装はあるのねんw

    ふと思ったんだけど、prototype.jsの

    IE : !!(window.attachEvent && !window.opera)

    この部分って!!document.allじゃダメだったのかな?
    IE判定したいんだもんね。
    いや使えない何かがあるんだろうw

    operaオブジェクトが持つメソッドはここにいろいろ書いてあったので参考までに。
    ユーザー JavaScript による制御: 仕様

    imgタグでonloadイベントを使う

    Ajaxianをダラ見してたらimgタグにonload記述があったのでさっそく実験してみたら・・・動いた!

    <img onload="this.style.width = '500px';" src="hogehoge.png" />
    

    全然知らなかったな~。
    一応Firefox3、IE7、Safari3.1で動作検証済みです。

    ■関連リンク
    kawama.jp: [JavaScript]imgタグでonLoad

    Safari3.1でCSSから文字にアウトラインをつける方法

    文字にアウトラインを付けるなら画像として作ってしまうのですが、Safari3.1では簡単にCSSから装飾ができるみたいです。
    このアウトランのCSSプロパティは正式にはCSS3の規格ではないので使うときには注意が必要だ。
    (仮に使うとしたら完全にSafariユーザーに対するエコヒイキになってしまいますねw)

    文字のアウトライン関連のプロパティは、現状ではCSS 3の規格には取り込まれておらず、W3Cに対して提案されている段階のものだ。

    via: 文字のアウトラインを表示する--FirefoxとSafariのCSS対応 - page3 - builder by ZDNet Japan

    アウトラインをつけるCSSの使い方

    div {
    font-size: 64px;
    font-weight: bold;
    color: skyblue;
    -webkit-text-stroke-color: darkblue;
    -webkit-text-stroke-width: 3px;
    text-decoration: underline;
    }
    

    他にも-webkit-text-stroke-colorと-webkit-text-stroke-widthをいっぺんに指定する-webkit-text-strikeや、Safariで色指定する-webkit-text-fill-colorといったプロパティがありますがここでは割愛しています。

    Safari3.1で表示した場合

    Firefox3で表示した場合

    IE7で表示した場合


    おお!Safariだけデコレーションされてます。
    他のブラウザではcolorプロパティの色が優先されているのでまったく別物になっていますね。
    さぁ使う機会はあるでしょうか?

    ■関連リンク
    文字のアウトラインを表示する--FirefoxとSafariのCSS対応 - builder by ZDNet Japan
    Safari 3.1でWebフォントを利用する--SafariのCSS対応 - builder by ZDNet Japan

    Safari3.1に搭載されたClient-side Database storageを試してみた

    ご存知のとおりHTML5の仕様でSelectors APIというものがありまして、これはクライアント側での永続化としてリレーショナルDBを使えるようにするものです。
    これを初めて知ったときは「ええっ!」となりましたが、CookieではなくDBに値を入れておくということがじょじょに可能になりつつあるようです。
    本当にオフラインでも動くサイトが出てきそうですね。

    具体的な話はamachangの記事で話されているのですが、基本的にはJDBC使ってDBにアクセスする雰囲気でいけます。
    (JavaScriptでトランザクションなんてことは想像もしてなかったですが・・・w)


    Database storage簡単な使い方

    openDatabase
    データベース開く
    transaction
    トランザクション張る
    executeSql
    SQLを実行する

    の3つの関数を使って、SQL実行しその結果を取得する!なんてことが出来るみたいです。
    では簡単ですが使い方をコードと一緒に見ていってみましょう!

    openDatabase関数の使い方

    windowオブジェクトにopenDatabaseプロパティがあるかを確認しています。
    あったらそれを使うし、なかったらSafariじゃないね~といった感じです。

    // DB初期設定
    try {
        if (window.openDatabase) {
            db = openDatabase("Test", "1.0");
            if (!db)alert("DB使えないよ!");
        }
        else
            alert("DBないね!");
    }
    catch (err) {
    }
    

    簡単ですね。


    transaction関数の使い方

    引数のtxはSQLTransactionオブジェクト。
    このオブジェクトがトランザクションを持っているので、そこからSQLを実行したりします。

    db.transaction(function (tx) {
        // ここでSQL実行したりします
    }
    );
    


    executeSql関数の使い方

    SQLを実行してくれる関数です。

    第一引数にクエリー文字列。
    第二引数にバインド変数の配列。
    第三引数に結果を取得した際に実行するfunction。

    db.transaction(function (tx) {
        tx.executeSql(query, [], function (result) {
            // 取得できた
        }
        , function (tx, error) {
            // こっちはエラー
        }
        );
    });
    

    おそらくこの関数をもっとも使うことになりそうです。

    Continue reading

    Safariを使って-webkit-box-shadowでシャドウを付ける

    CSS3のbox-shadowプロパティを使うと簡単にドロップシャドウを付けれるみたい。
    画像とかに付けると見栄えもかっこいい感じになるから早く全ブラウザで対応してほしいところです。
    これが導入されればわざわざPhotoshopでドロップシャドウを付ける必要もなくなる?のにね。

    Safari3では-webkit-box-shadowという名前になっているのでちょっと使ってみました。
    以下が簡単なサンプルです。

    <style>
    <!--
    .shadow {
         -webkit-box-shadow : rgba(0, 0, 0, 0.498039)0px5px10px;
        background - color : rgb(255, 240, 70);
        height : 250px;
        width : 250px;
    }
    -->  </style>
    <div class="shadow"></div >

    これをSafari3で表示させると上の画像のようにドロップシャドウがついた状態になります。
    う~ん、かっこいい!

    ■参考リンク
    WebKit HTML 5 SQL Storage Notes Demo
    ボックスにドロップシャドウの効果をつける--Safari 3のCSS対応 - builder by ZDNet Japan

    StrutsでResetを使わずにCheckbox問題を解決する方法

    Strutsを使っていて且つスコープをSessionにしている場合に結構問題になってくるのが、checkboxを外したときのHTTPPostについてだと思う。
    HTTPの仕様でチェックがついていればvalueがPostされ、チェックがついていない場合はうんともすんとも言わない。

    これを解決する方法としてStrutsが用意しているメソッドがresetメソッドだ。
    resetメソッドを使うとActionFormのセッターが動きだす前に初期化することができる。
    もしスコープをRequestにしているなら毎回インスタンスが生成されるので問題はないが、Sessionだとresetメソッドを使ってcheckboxに対応したプロパティを初期化する必要がある。

    resetメソッド

    public void reset(ActionMappingarg0, HttpServletRequestarg1) {
        this.checkboxVal = "false";
    }
    

    でも独自に実装したStrutsや、resetメソッドを呼ぶことができない場合にはこれまたやっかいになる。
    チェックボックスのonclickイベントで別に用意したhiddenに値を格納し、なんとかサーバーサイドで判断することも可能だがこれだと面倒すぎてcheckboxを使いたくなくなるw

    これを簡単に解決してくれるのが、同じActionFormのプロパティを持つhiddenを使う方法だ。

    JSPの書き方

    <html:multibox name="setterCheckForm" property="setterCheckBase.hogehoge">checked</html:multibox>aaa
    <nested:hidden property="setterCheckBase.hogehoge" value="unchecked"/> 

    ここで重要なのがcheckboxやmultiboxは必ずhiddenより前に書くこと。推測だがPostされたときのメッセージボディに並べられた順番にStrutsのセッターが動き出すので、もしhiddenが最初に書いてあるといつまでたってもcheckboxのほうがセットされなくなってしまう。

    たったこれだけでチェックが入っていればcheckedがPostされ、チェックが入っていない場合はuncheckedがPostされる。
    チェックが入った場合にPostされないのをうまく使ったトリックだが、保守性には少しかけるかもしれないのでご用心。

    Firebugが入っているかをJavaScriptから判断する方法

    簡易版FirebugのFirebug Liteのコードを見てて思ったのが、FirefoxでFirebug Liteを埋め込んだページをロードした場合に、ちゃんと既存のほうのFirebugが開いたのでどっかで判断しているじゃないかと思ったら1行目に書いてあったw

    if (("console" in window) || ("firebug" in console)) {
        alert("Firebugが入っています");
    }
    

    初めのif文がまさにそれ!
    alertは自前で付け足したものですが、if文のところはそれでしょう。

    でももしwindowオブジェクトにconsoleがなかった場合に、次の("firebug" in console)でconsoleというオブジェクトが存在しないためにエラーなるかも。
    いろいろ実験した結果ブラウザにごとに条件分けしないといけないかもです。

    続きで実験用のボタンをご用意しています。

    Continue reading

    innerHTMLに値がないとgetElementByIdでnullになるパターン

    onloadやDomContentLoadedを待たずにJavaScript処理をしたい場合は多々あるのですが、例えば以下のようにあるエレメントの下にScriptタグを書いて実行させる場合にinnerHTMLの値が空っぽだとdocument.getElementByIdで取得したときにnullになってしまう現象があった。

    <span id="txt"></span>
    <script type="text/javascript">
    <!--
    alert(document.getElementById("txt"));
    //-->
    </script>
    

    alertはnullと表示される。

    <span id="txt">aiueo</span>
    <script type="text/javascript">
    <!--
    alert(document.getElementById("txt"));
    //-->
    </script>
    

    alertは[object HTMLSpanElement]と表示される。

    divタグでやっても一緒だった。
    divとかspanはあくまでも枠やラベル的なものでしかないからダメなのかな。

    以下のようにbutton要素の場合はinnerHTMLがなくても大丈夫だった。

    <button id="txt"></button>
    <script type="text/javascript">
    <!--
    alert(document.getElementById("txt"));
    //-->
    </script>

    また当然のようですが、onloadを待てばちゃんとエレメントのオブジェクトが取得できる。
    これが出来ないとinnerHTMLに値を挿入できなくなっちゃうしね。

    <script type="text/javascript">  <!--
    function f() {
        alert(document.getElementById("txt").innerHTML);
    }
    //-->
    </script>
    <body onload="f();">
    <span id="txt"></span >
    </body>

    Firefox2でonload前にalert呼ぶとstyleが崩れる

    たとえばこんな感じで「background-color : #888;/*(灰色)*/」背景を指定しておいて、DOM構築が終わる前にalertを呼んじゃうとFirefox2で変な挙動になる。

    <style>
    <!--
    * {
        padding : 0px;
        margin : 0px;
    }
    body {
        background - color : #888;
    }
    -->  </style>
    <script type="text/javascript">
    <!--
    // 多分DOM構築前に呼んでるからかな?
    alert("");
    //-->
    </script>
    

    alertが出る前と出た後で背景が白いが、Alt+Tabとかでいったん違うウィンドウに切り替えてからもう一度Firefox2をアクティブにすると切り替え前にアクティブにしていたウィンドウの枠ぶんだけ灰色になっている。

    IE7やFirefox3ではならなかったので、Firefox2のバグなのかな。
    まぁDOM構築前にalertを呼ぶことはそうそうないからいいや。

    JavaScriptでちょっと面白いコード - 式クロージャ

    素人がプログラミングを勉強するブログさんでちょっと面白い書き方を教わったのでメモメモ。

    このコードは

    var Class2 = function()function()function()alert("b");
    Class2()()();
    

    このコードと同義。

    var Class = function () {
        return function () {
            return function () {
                alert("a");
            }
        }
    }
    Class()()();
    

    呼び出し方がClass()()()とちょっと変わってて面白い。
    クロージャーを使うときに2個まで括弧を付けて書くことはあるけど、3個以上はなかったな。

    追記:
    どうやらFirefox3(JavaScript1.8)から採用された式クロージャという書き方みたい。

    1.7前まではこうかかないといけなかったんですが

    function(x) { return x * x; }

    via: New in JavaScript 1.8 - MDC

    1.8から

    function(x) x * x

    via: New in JavaScript 1.8 - MDC

    このようにreturn文を書かなくても値が返ってくれる。
    だから見たことなかった構文だったんだ!w

    MacOSXのWhiteRoomのようなエディタ「JDarkRoom」

    MacOSXのWhiteRoomのようなエディタ「JDarkRoom」

    MacOSXのWhiteRoomのようなエディタ「JDarkRoom」

    MacOSXのWhiteRoomのようなエディタ「JDarkRoom」

    JDarkRoom

    MacOSXを使っている方なら触ったことがあるかもしれませんが、WhiteRoomというエディターは画面がまるでDOS画面のようにエディターが全画面を覆ってしまうエディター。
    どんな利点があるのかというと作業を集中するということですが、これがまた結構集中できるのです。

    とくに時事的なブログを書いている方にとっては、ブラウザーやらメーラーやらiTunesなんて画面内には必要ない場合が多いのでこういったエディターを使って記事を書くとなかなかなスピードで書けてしまうのです。

    上にあえて3パターンの画像を掲載してみましたが、カスタマイズすると結構かわいげがある自分オリジナルが作れそうです。

    でもWindows版のJDarkRoomがフリーウェアなのにMacOSXのWhiteRoomがシェアウェアなのは一体なぜ~~~!

    Java1.4以上が入ってないとダメなようですが、一応.NET版のリンクも貼っておきますね。

    .NET版のDarkRoomは以下からどうぞ。
    集中力に自信のない人のためのテキストエディタ「Dark Room」:オープンソースを毎日紹介

    [via]
    MOONGIFT

    JavaScriptでローカルファイルにアクセスする方法

    Q2. JavaScriptでローカルファイルを読み/書きたいのですが… A2. Webではセキュリティ制約により絶対無理です。できたら恐ろしいことに…

    via: JavaScriptプログラムメモ|プログラムメモ

    ここに書かれていた内容でJavaScriptからローカルファイルにアクセスは出来ないと書いてあったので、そういえばAjaxで出来たような・・・と。

    単純に「dataだよ」という文字列を持つ「data.html」というローカルファイルにアクセスする方法をprototype.jsとjqueryの場合で試してみました。

    prototype.jsの場合

    document.observe("dom:loaded", function () {
        var r =  new Ajax.Updater("data", "data.html", {
            "method" : "get";
        }
        );
    }
    );
    

    ※IEではうまくいかないみたい。Firefoxで試したらちゃんと取得できました。

    jquery.jsの場合

    $(function () {
        $("#data").load("data.html");
    }
    );
    

    さすがはjquery!
    IEでもFirefoxでもちゃんとローカルファイルにアクセスできました。
    ちょろっとAjaxのコードを書こうとしてもprototype.jsだとAjax用のオプションを設定したりちょっぴり面倒。その点jqueryだと特にオプションを意識しなくてもサラサラと記述できるので簡単ですね。

    CSSでセロハンテープなどの装飾を施す方法

    Web Designer Wallという海外のWebDesignのサイトで紹介されていたCSSのテクニックですが、最近みなさんブログにアップされているようなのでボクも便乗。

    Web Designer Wallを見ていただけると分かるのですが、デザインが美しすぎるんです!
    タイトルヘッダーのぐるぐるした感じがクリエイティブだし、キチっとしたラインを作らずにずらすテクニックがとってもうまいです。

    そこで紹介されていたセロハンテープのテクニックなどは今後使えそうだと思ったのでメモメモ。

    例えば上の画像のようにピンだったりセロハンテープだったりを施したい場合は以下のコードになります。

    CSS

    .photo {
        float : left;
        height : 130px;
        margin : 30px;
        position : relative;
        width : 180px;
    }
    .sample1span {
        background : transparenturl(images / pin.png)no - repeatscroll0 % ;
        display : block;
        height : 21px;
        left : 90px;
        position : absolute;
        top :- 12px;
        width : 28px;
    }
    .sample2span {
        background : transparenturl(images / tape.png)no - repeatscroll0 % ;
        display : block;
        height : 27px;
        left : 50px;
        position : absolute;
        top :- 12px;
        width : 77px;
    }
    .sample3span {
        background : transparenturl(images / paper - clip.png)no - repeatscroll0 % ;
        display : block;
        height : 60px;
        left :- 2px;
        position : absolute;
        top :- 5px;
        width : 30px;
    }
    .sample4span {
        background : transparenturl(images / tape2.png)no - repeatscroll0 % ;
        display : block;
        height : 32px;
        left : 30px;
        position : absolute;
        top :- 13px;
        width : 115px;
    }
    .sample11span {
        background : transparenturl(images / floral - corner.png)no - repeatscroll0 % ;
        display : block;
        height : 72px;
        left :- 15px;
        position : absolute;
        top :- 22px;
        width : 122px;
    }
    .sample14span {
        background : transparenturl(images / glossy - gradient.png)repeatscroll0 % ;
        display : block;
        height : 84px;
        left : 5px;
        position : absolute;
        top : 5px;
        width : 170px;
    }
    

    HTML

    <div class="photosample1">
    	<a href="#">
    		<span></span>
    		<img alt="image" src="images / 9.jpg"/>
    	</a>
    </div>
    <div class="photosample2">
    	<a href="#">
    		<span></span>
    		<img alt="image" src="images / 13.jpg"/>
    	</a>
    </div>
    <div class="photosample3">
    	<a href="#">
    		<span></span>
    		<img alt="image" src="images / 2.jpg"/>
    	</a>
    </div>
    <div class="photosample4">
    	<a href="#">
    		<span></span>
    		<img alt="image" src="images / 9.jpg"/>
    	</a>
    </div>
    <div class="photosample11">
    	<a href="#">
    		<span></span>
    		<img alt="image" src="images / 8.jpg"/>
    	</a>
    </div>
    <div class="photosample14">
    	<a href="#">
    		<span></span>
    		<img alt="image" src="images / 5.jpg"/>
    	</a>
    </div>
    

    外側にいるdivタグにはposition:relative;が指定されているので、その中にいるspanタグのposition:absolute;はdivタグから相対指定になりますね。
    これでちょうどいい場所に装飾用の画像を表示させています。
    意外にも一般的な方法を使っているのですが、かわいらしい画像を使って実装されているともっとトリッキーな方法なんじゃないかと妄想させられますw

    こうなってくるとイラストレーターやPhotoshopを使いこなせるのが最も大切?になってくるのでしょうかね?
    早く覚えねば・・・

    デモは以下のサイトから見ることができます。(楽しいですよ!)
    Firebugで覗いちゃってください。
    Demos | CSS Decorative Gallery

    JavaScriptからVBScriptを呼ぶ方法

    ほぼ使うことはないかと思いますが、ちょっと調べてみました。

    execScriptでVBScriptをコールする

    <script language="JavaScript">
    <!--function msg() {
        execScript("MsgBox('VBscript!')", 'VBScript');
    }
    // -->
    </script>
    <input type="button" value="MsgBox" onclick="msg();">
    
    IE6.0
    使える
    IE7.0
    使える
    Firefox2.0
    使えない
    Safari3.1
    使えない
    Netscape7.1
    使えない
    Opera9.25
    使えない

    JavaScriptからVBScriptの関数をコールする

    <script language="VBScript">
    Function VbConfirm()
        VbConfirm = MsgBox("メッセージ", 257, "メッセージタイトル")
    EndFunction
    </script>
    <script language="JavaScript">
    function test()
    {
        var ret = VbConfirm();
    }
    </script >  < inputtype = "button"name = ""value = "アラート"onclick = "test()"/>
    
    IE6.0
    使える
    IE7.0
    使える
    Firefox2.0
    使えない
    Safari3.1
    使えない
    Netscape7.1
    使えない
    Opera9.25
    使えない

    なんだ基本IEのみなんじゃん。

    でもIE6.0とIE7.0で実行は出来るのだがなぜか「test()」の後にセミコロンを入れるとステートメントエラーが発生してしまう。
    セミコロンを取ればうまくいく・・・う~ん。
    まぁいいやw

    JavaScriptでリフレクション

    意外にも出来るみたい。

    // クラスの定義
    var Hoge = function () {
    }
    Hoge.prototype = {
        alert : function () {
            window.alert("");
        }
    }
    // リフレクション
    var bar = this['Hoge'];
    var methodName = 'alert';
    (new bar())[methodName]();
    

    これでDIコンテナとか作ってみたら面白いかも。
    使うかどうかは分かりませんがw

    ■関連リンク
    リフレクション (情報工学) - Wikipedia

    jQueryのクラス定義はトリッキーでかっこいいよ

    prototype.jsと違ってjQueryはメソッドを呼ぶたびにjQueryオブジェクトを返します。
    なのでオブジェクト汚染がないのがメリットですが、クラスの定義の仕方がちょっぴりトリッキーだったのでメモメモ。

    prototype.jsのクラス定義

    var Class = {
        create : function () {
            //オブジェクトをリターン
            return klass;
        }
    };
    

    これは比較的JavaScripterにとっては安心できるコードですね。
    クラスという変数に連想配列を入れてあたかもクラスのように見せています。


    Element.ClassNames = Class.create();
    Element.ClassNames.prototype = {
    initialize : function (element) {
    this.element = $(element);
    }
    }

    こっちは上で紹介したClass.create()を使ってオブジェクトを取得し、そのprototypeにメソッドを追加していっています。
    こっちのほうがプロトタイプベースな感じが出ててJavaScript~!って感じがします。

    jQuery.jsのクラス定義

    jQueryを見てみると初めに

    (function () {
        /*
        * jQuery 1.2.6 - New Wave Javascript
        *
        * Copyright (c) 2008 John Resig (jquery.com)
        * Dual licensed under the MIT (MIT-LICENSE.txt)
        * and GPL (GPL-LICENSE.txt) licenses.
        *
        * $Date: 2008-05-24 14:22:17 -0400 (Sat, 24 May 2008) $
        * $Rev: 5685 $
        */
    

    という部分がありますが、一見普通のコメントか~と思っていると1行目になんかいる!
    そう、匿名関数(無名関数)ですね。
    つまり、jQuery.jsの全体をこの匿名関数で覆われていて、一番最後の行(3549行目)で実行しています。

    });})
    (); ←ここですね。
    

    なかなかいやらしいですね。

    ではjQuery.jsのコードはかなり長いので比較的コンパクトにまとめてみました。
    以下がそれです。

    (function () {
        var jQuery = window.jQuery = window.$ = function (ele) {
            return new jQuery.fn.init(ele);
        };
        jQuery.fn = {
            //jQuery Instance
             init : function (ele) {
                this.prop = ele;
            }
            , alert : function (x) {
                window.alert(x);
            }
        }
        jQuery.fn.init.prototype = jQuery.fn;
    }
    )();
    

    分かりやすくするためにコードを簡単にしていますが、大体こんな感じでしょう。
    これを実行するには普通にjQueryを使う感じで実行できます。

    $().alert("hogehoge");
    

    初めの$()でjQueryのオブジェクトが返ってくるので、後はメソッド定義されているalertを呼び出せば実行できるという感じです。
    ただこのコードにはjQueryらしいスパイスがふんだんに盛込まれているのでちょっと説明してみましょう。

    Continue reading

    ActionScriptでクロージャを使う方法

    戻り値にFunction型を指定できるので普通にクロージャって概念があるのね。

    package {
        import flash.display.Sprite;
        public class astestextendsSprite {
            public function astest() {
                var func : Function = closure();
                func();
            }
            private function closure() : Function {
                var str : String = "test";
                return function () : void {
                    trace(str);
                }
            }
        }
    }
    

    実行するとコンソールに「test」と出力されます。

    jQueryの再帰呼び出しはとってもトリッキー

    再帰呼び出しは関数内で自分自身を何回か呼ぶことを指しますが、jQueryの再帰呼び出しはちょっぴりオシャレ。

    例えば2340行目あたりでブラウザ毎の処理をしていますが、あるタイミングまでひたすら再帰呼び出しをしています。

    jQuery:1.2.6

    // If IE is used and is not in a frame
    // Continually check to see if the document is ready
    if (jQuery.browser.msie && window == top)(function () {
        if (jQuery.isReady)return;
        try {
            // If IE is used, use the trick by Diego Perini
            // http://javascript.nwbox.com/IEContentLoaded/
            document.documentElement.doScroll("left");
        }
        catch (error) {
            setTimeout(arguments.callee, 0);
            return;
        }
        // and execute any waiting functions
        jQuery.ready();
    }
    )();
    

    一見単にif文があるだけのように見えますが、if文のすぐ右側から無名関数を記述しています。
    そしてその無名関数内で「setTimeout( arguments.callee, 0 );」をしているので自分自身は無名関数になる。
    おお~!これなら再帰呼び出しされるのは無名関数内にとどまるからコードを見ていても理解しやすい。

    以下適当に作ったサンプルコード。
    遠目で見ると関数が存在しないように見えますが、if文の右側から関数が始まっています。

    var num = 0;
    if (num == 0)(function () {
        try {
            num++;
            if (num != 5)throw "hoge hoge";
        }
        catch (error) {
            // numが5になるまで再帰呼び出し
            setTimeout(arguments.callee, 0);
            return;
        }
        // 5
        console.log(num);
        }
    )();
    

    値の監視をとかをするときにこのトリックは使えそうですね。

    UTF-8で保存されたMSゴシックはIE6.0で崩れる

    MSゴシックでギュギュっと同じ幅にされちゃうから崩れるのかな?
    なので基本的にはMSPゴシックを使うようにしています。

    <style>
    <!--
    .small {
        /* これは崩れる */
        font - family : 'MS ゴシック';
        /* これは崩れない */
        /* font-family: 'MS Pゴシック'; */
    }
    -->
    </style>
    <!-- IE6.0で崩れる -->
    <div class="small">
    株式会社TEST<br /> うんたらかんたら </div>

    なぜかIE6.0限定です。

    SafariではCSSクラスの中括弧がないと無効になる

    記述忘れとしてCSSクラスの中括弧を閉じなかった場合に、WinSafari・MacSafariではそのCSSクラスが無効になってしまう。
    まぁ忘れずにちゃんと書けばよいのですが、試しに忘れちゃった場合を想定してみました。

    以下サンプルコード。

    <style>
    <!--
    div#box {
      position : absolute;
        top : 100px;
        left : 100px;
        width : 100px;
        height : 100px;
        border : 1pxsolid#888;
     /* ここに閉じ中括弧がない */
    -->
    </style>
    <div id="box">
    が~~~ん!
    </div >

    div#boxのクラスは閉じ括弧がないようにしています。
    これをSafariで表示した場合にはとくにCSSが効いていない上体で表示されます。

    またWindows版のモダンブラウザの挙動を以下にまとめました。

    IE6.0
    有効
    IE7.0
    有効
    Firefox2
    有効
    Opera9.25
    有効
    Netscape7.1
    有効
    WinSafari
    無効
    MacSafari
    無効

    ちなみに開始中括弧がなくてもダメのようです。

    知ってれば問題なしっ!

    Ruby on Railsの年表

    Ruby on Railsのリリース履歴(日付は日本時間) 2004年7月25日
    2004年12月17日
    2005年12月14日
    2006年3月29日
    2006年8月10日
    2007年1月19日
    2007年11月25日
    2007年12月7日
    2007年12月18日 Rails 0.5.0リリース
    Rails 0.9.0リリース
    Rails 1.0リリース(正式版リリース)
    Rails 1.1.0リリース
    Rails 1.1.6リリース(セキュリティホールへの対応など)
    Rails 1.2.1リリース
    Rails 1.2.6リリース(1.2系の最終バージョン)
    Rails 2.0.0リリース(RESTサポートの強化)
    Rails 2.0.2リリース(本稿執筆時点の最新バージョン)

    via: Strutsの知識を基に、Ruby on Railsを学ぶ方法 − @IT自分戦略研究所

    Javaの年表

    avaの年表
      1996年 1月
    1997年 2月
    1998年12月
    2000年 5月
    2002年 2月
    2004年 9月
    2006年12月 JDK 1.0
    JDK 1.1
    JDK 1.2
    J2SE SDK 1.3
    J2SE SDK 1.4
    J2SE SDK 5.0
    JDK 6

    via: Javaエンジニアにこそ、Rubyの良さが分かる − @IT自分戦略研究所

    クロージャのスコープは関数オブジェクト単位だよ

    closure関数の戻り値の無名関数(method)を実行するとまず無名関数内にiという変数があるか確かめる。
    自分自身にもっていないのでスコープチェーンで上位のclosure関数を見に行きi変数があるのでそれをインクリメントしてアラート。

    closure関数から飛び出た無名関数内でi変数をいつまでも参照しているので、オブジェクトは破棄されない。やった〜。

    そしてclosure関数をもう一度呼び出してクロージャを取得し、同じことを実行するとさっきまで使っていたクロージャとは別のスコープだということが分かる。

    当たり前と言えば当たり前なのだが、関数ごとにCallオブジェクトが作られるので別々のクロージャ空間とも言うべきスコープになる。
    これってActionScriptにもあるのかな?

    function closure(x) {
        var i = x;
        return function test() {
            i++;
            alert(i);
        }
    }
    var method = closure(10);
    //11
    method();
    //12
    method();
    var method2 = closure(20);
    //11
    method2();
    //12
    method2();
    

    window.window.window.windowはwindowオブジェクト

    windowプロパティはWindowオブジェクトの参照先を保持するプロパティなので、windowプロパティ、つまりwindowオブジェクトのwindowプロパティもまたwindowオブジェクトなのである。
    なんか書いてて分かりにくくなってしまったが、以下のコードを見てもらえば一目瞭然だろう。

    console.log(window.window.window.window.window.window.window.window);
    window.window.window.window.window.window.window.window.alert("test");
    

    どんだけやねんっ!w

    IEでliにpadding-bottomを入れたときに色が覆いかぶさる

    IE6.0とIE7.0でしか起こらないのだが、ちょっぴりヘンテコなバグっぽいのでハマってしまったのでメモメモ。

    divタグの中にulタグとliタグが入っていて、そのliにpadding-bottomが掛かっていた場合にliを含めているdivタグの背景色がスクロールしたときにはみ出してしまう。
    あえてスクロールバーを出すために一つdivタグを用意しているが、そこは今回のとは特に関係はありません。
    問題なのはその下にあるclass="navi"で指定しているdivタグだ。

    ダメなパターン

    <style>
    <!--
    * {
    padding: 0px;
    margin: 0px;
    }
    div.navi {
    padding-bottom:15px;
    }
    div.wrap {
    background-color:#ECFBDE;
    }
    .wrap2 {
    padding-bottom:10px;
    }
    -->
    </style>
    <!-- スクロールさせたいため -->
    <div style="margin-top: 800px;">
    </div>
    <div class="navi">
    	<div class="wrap">
    		<ul>
    			<li class="wrap2">あああああ</li>
    			<li class="wrap2">あああああ</li>
    			<li class="wrap2">あああああ</li>
    		</ul>
    	</div>
    </div>
    <div class="navi">
    	<hr>
    </div>
    

    なんとか解決する方法?みたいなものを発見したので以下にメモしておく。

    とりあえずうまくいくパターン

    <style>
    <!--
    * {
    padding: 0px;
    margin: 0px;
    }
    div.navi {
    padding-bottom:15px;
    /* width:800px; */ /* widthを入れるとうまくいく */
    }
    div.wrap {
    background-color:#ECFBDE;
    /* border: 1px solid; */ /* borderを付けるとうまくいく */
    }
    .wrap2 {
    padding-bottom:10px;
    }
    -->
    </style>
    <!-- スクロールさせたいため -->
    <div style="margin-top: 800px;">
    </div>
    <div class="navi">
    	<div class="wrap">
    		<ul>
    			<li class="wrap2">あああああ</li>
    			<li class="wrap2">あああああ</li>
    			<li class="wrap2">あああああ</li>
    		</ul>
    	</div>
    </div>
    <div class="navi">
    	<hr>
    </div>
    

    あんまり正攻法とは言えないが、以下のことを実施すると背景色がはみ出るのが防げた。
    borderをつけるほうはborderを使わないパターンの時には使えないのでwidthが有効だろう。

    • widthを入れるとうまくいく
    • borderを付けるとうまくいく
    • そもそもpadding-bottomを付けなければうまくいく

    なんかこれ以外にもいい方法がありそうだが、今のところ発見できなかった。

    Internet Explorer (Windows) CSSバグリストを見ても見当たらなかったので、今後もハマりそうな予感大!
    クロスブラウザ対応は大変っすね。特にIE!
    なお標準モード、互換モードどちらもでもなりました。なのでDOCTYPE宣言は上記コードには含めていません。

    CSSで画像の一部を使える「CSS Sprites」

    第10回 CSS Spritesでサイトを高速化で紹介されていたCSS Spritesが気になった。
    CSS Spritesとは例えばサイトアクセス時に各々の画像を別にするのではなく、1枚の大きな画像をダウンロードさせて使いたい部分を表示するという方法。

    Mapを使って画像の一部を使うのではなく、background-positionプロパティで同じことを実現しているみたいです。
    こんなこと出来たんですね。

    続きでCSS Spritesを試してみたいと思います。

    Continue reading

    世界をアンダーグラウンドな世界に置換するブックマークレット

    天才を変態に置き換えるブックマークレット - てっく煮ブログこちらで「天才」から「変態」に置換するブックマークレットが紹介されていたので、文字だけ変えて遊んでみた。

    javascript:void(document.body.innerHTML=document.body.innerHTML.replace(/世界/gi,'アンダーグラウンドな世界'))
    

    サイト内に「世界」というキーワードがあった場合に、「アンダーグラウンドな世界」と置換されます。
    すんごいくだらないけど、なんか面白い。
    自分のブログにこのリンク貼っとこうかな。

    Mac OS X LeopardにTomcat6をインストールしてみた

    Tomcatのダウンロード

    以下のサイトからtar.gzのファイルをダウンロードする。
    Apache Tomcat - Apache Tomcat 6 Downloads

    Tomcatのインストール

    まずはダウンロードしたファイルをTomcatをインストールしたい場所に移動します。
    ここでは「/usr/local/tomcat」にしました。

    mkdir /usr/local/tomcat
    sudo mv apache-tomcat6.0.16.tar.gz /usr/local/tomcat
    

    まずはダウンロードしたファイルを展開します。

    cd /usr/local/tomcat
    sudo tar zxvf apache-tomcat6.0.16..tar.gz 
    

    すると「/usr/local/tomcat/apache-tomcat6.0.16」ディレクトリができるので、こいつにシンボリックリンクを貼ります。
    以下のエントリーを参考にしました。
    CreativeStyle - Mac OS X(Leopard)にTomcatをインストール

    sudo ln -s /usr/local/tomcat/apache-tomcat6.0.16/ /usr/local/tomcat/current
    

    こうしておくと「/usr/local/tomcat/current」がapache-tomcat6.0.16と同じ意味になるのでこれは便利。

    JAVA_HOMEを設定

    Tomcatが参照できるようにJAVA_HOMEを環境変数に設定する。

    export 環境変数として変数を設定する 書式 export 変数名[=設定する値]

    via: UNIXコマンドリファレンス
    echo export JAVA_HOME=/Library/Java/Home >> .bash_profile
    

    権限を付与する

    sudo chown -R username:staff apache-tomcat-6.0.16
    sudo chown -R username:staff current
    

    WTPを使ってServerを立ち上げようとしたのですが、上記権限を付与せずに実行したらエラーが出てハマってしまった。
    この権限を付与せずにWTPのServerを作っても「Servers」ディレクトリには何も作成されないので、Eclipse側からエラーが出ていました。

    Tomcatを起動する

    sudo /usr/local/tomcat/current/bin/startup.sh
    

    「http://localhost:8080/」にアクセスするとTomcatのネコが表示されればOKです。

    ApacheはLeopartに初めから入って入っているんだけど、Tomcatは入っていないんですね。
    インストールするのが勉強になったので、OKです!w

    Mac OS X LeopardでPerlのHello Worldしてみた

    30A230C330D730EB - Mac OS X Leopard - 628088534ED569D8

    Mac OS X Leopardには開発環境がめちゃくちゃ整っている。
    以下のAppleの仕様に書いてあるとおり、オープンソース系の言語が標準だからこれは溜まらん。
    アップル - Mac OS X Leopard - 技術仕様

    開発

    • Xcode 3 IDE(Interface Builder 3付属)
    • Instruments
    • Dashcode
    • AppleScript Studio
    • Automator 2
    • Shark
    • GCCコンパイラ&ツールセット(FSF.orgプロジェクト)
    • DTrace(Sunプロジェクト)
    • Java JDK一式(javac、javadoc、ANT、Mavenツールを含む)
    • Apache Webサーバ
    • AppleScript
    • Ruby and the Ruby on Rails frameworks
    • Python
    • Perl
    • PHP
    • SQLite

    via: アップル - Mac OS X Leopard - 技術仕様

    なので今まで勉強していなかったPerlもRubyといっしょに勉強していこうと思う。
    だって環境があるのに使わないのはもったいないですもんね。
    ちょうどTextMateという最高のEditorもあるので合わせて勉強!

    まずはPerlのバージョン

    perl -version

    どうやら5.8.8。

    Perlコードの作成(HelloWorld)

    #! /usr/bin/perl
    
    

    print "こんにちは!¥n";

    これをhello.plとして保存、そして実行。

    perl hello.pl

    こんにちはと表示される。
    よし、まずはHelloWorldをクリアした。
    後は地道に遊んでいこう。

    なおPerlの勉強にはカテゴリ別詳細目次 - サンプルコードによる Perl 入門ここがめちゃくちゃ読みやすい。

    ちなみにTextMateには、PerlMateという機能があって「Command + R」でTextMate上でPerlを実行できる。
    なのでターミナルからいちいち実行しなくてもいいみたい。
    TextMate〜〜。

    hello.pl 2014 PerlMate

    TextMateのBundle(拡張)を簡単に導入する方法

    Validcode ~ Projects - GetBundle

    Railsに最適なテキストエディター「TextMate」を入れてみた
    で紹介したTextMateですが、どうやら入力補完の機能を拡張できるみたいです。

    例えばデフォルトではJavaScriptの入力補完が入っていますが、jQueryやらPrototype.jsの入力補完もしたい〜という人向け。

    他にも様々なBundleがありどれもこれも魅力的です。
    SQLを発行するためのBundleなんてのもありました。

    このBundle(拡張)を簡単にインストールするには、GetBundleというBundleを入れるとぐぐ〜と楽になります。
    以下からダウンロードしてきて、TextMateのBundleディレクトリに投入しちゃってください。
    Validcode ~ Projects - GetBundle

    投入する先は
    「Applications/TestMate.app/SharedSupport/Bundles」
    の中です。

    後はTextMateのBundleからGetBundleを選択するとInstall Bundleがありますので、こいつをクリック。
    Bundleを選ぶ画面になるので、後は好きなのを入れまくり。
    とりあえずjQueryとかJavaScriptで必要になるのをコロコロ入れています。
    ただjQueryの補完がHTMLファイル上でうまくできないので、なんでなのか調査中です。

    Mac OS X LeopardでRailsとMySQL連携で文字化けする場合の対処

    Mac OS X LeopardでRailsで遊べる環境を構築するまでで環境構築までは終わったんですが、次は文字化けに悩まされるハメに・・・

    やっとのことで解決しました!

    Rails側の文字コード設定

    database.yml

    development:
      adapter: mysql
      database: railsTest
      username: root
      password: 19805525
      timeout: 5000
      host: localhost
      encoding: utf8 ←ここです
      socket: /tmp/mysql.sock
    

    application.rb

    class ApplicationController < ActionController::Base
      # Pick a unique cookie name to distinguish our session data from others'
      session :session_key => '_bookTest_session_id'
      before_filter :set_charset
      private
      def set_charset
        headers["Content-Type"] = "text/html; charset=UTF-8"
      end
    end
    

    environment.rb

    1行目に

    $KCODE = "UTF8"
    

    MySQL側の文字コード設定

    ■文字コードを設定する

    /etc/my.cnf を編集する。

    [client]
    default-character-set=utf8

    [mysqld]
    default-character-set = utf8
    skip-character-set-client-handshake
    character-set-server = utf8
    collation-server = utf8_general_ci
    init-connect = SET NAMES utf8

    via: MySQL 文字化けを防ぐ、文字コードの確認と設定 | 渋谷生活

    ボクは/etc/my.cnfがなかったので以下の手順を踏んだ。

    ■/etc/my.cnfが無いとき

    インストールしたMySQLの中のサンプルをコピーする。

    # cp /usr/local/mysql/support-files/my-medium.cnf /etc/my.cnf

     再起動して有効になる。

    via: MySQL 文字化けを防ぐ、文字コードの確認と設定 | 渋谷生活

    この状態で

    sudo /usr/local/mysql/bin/mysql -u root -p railsTest

    でMySQLにログインし、
    mysql > status
    で以下が表示されるようになる。

    30BF30FC30DF30CA30EB 2014 mysql 2014 80�4

    また、
    mysql > show variables like 'char%';
    で以下のようにUTF-8だらけになればよい。

    30BF30FC30DF30CA30EB 2014 mysql 2014 80�4


    実はDatabaseを作成するときの文字コード指定を間違えていっこうに
    db characterset : latin1
    になったままになってハマってしまった。

    これだと上記の手順をすべて踏んでも文字化けが解消されなかった。
    なので、ちゃんとカラムを作成するときも以下のように文字コードを指定する必要がある。

    localhost / localhost / railsTest / books | phpMyAdmin 2.11.6
    あとRailsなのでidカラムにはオートインクリメントを付けること。
    これもさっきすごいハマってしまった。

    またmy.cnfのパーミッションは気をつけないと永遠にハマる可能性がある。
    ボクは初め問答無用で
    chmod 777 /etc/my.cnf
    ってしてたんだけど、これだとMySQLを実行した際にignoredって表示されて無視されてしまった。

    以下の記事で解決した。


    chown mysql:mysql my.cnf

    chmod 600 my.cnf


    が正解です。my.cnf は

    mysqld_safe が 動作する際に mysqlユーザーのみ参照できればいいわけで。mysqlユーザーがオーナーであれば 600 でいいわけです。そうすれば、world-writable にならずに済みます。


    via: Eriane ver 0.6.1 » 忙しい・・・

    本日はハマりまくりな1日でした〜。
    疲れた・・・w

    ■参考リンク
    sunadaaの日記 : my.cnfを無視させないようにする - livedoor Blog(ブログ)
    文字化け対策のためのあれこれ | Katawara.*
    MySQL 文字化けを防ぐ、文字コードの確認と設定 | 渋谷生活

    Mac OS X LeopardでRailsで遊べる環境を構築するまで

    Mac OS X Leopardにはなんと初めからRuby On Railsが導入されているみたい。
    Rails on OS X !? - Ruby on Rails、Mac OS X Leopardに搭載へ | エンタープライズ | マイコミジャーナル

    せっかくなんでとりあえずRailsが書ける環境まで構築してみた。
    まだMacの操作にも慣れていないのでかな〜りハマりながらになってしまったが、とりあえずできたような気がする。

    RailsはやらないけどRubyを書いてみたいって人にとってもすばらしい環境ですね。
    試しにターミナルで

    ruby -v

    と入力するとRubyのバージョンが表示される。Macで開発をしたことがないけど、これからガリガリ書いていきたい。

    ではMac OS X LeopardでRailsを開発するためのツールをインストールしてみる。


    Aptanaのインストール

    Download Aptana Studio 1.1 | Aptana
    ここからAptanaをダウンロードしてインストール。

    AptanaはすぐれたEclipseベースのIDEで、ボクはJavaScriptやHTMLの作成でよく使っていました。
    そのAptanaにRails開発環境のRadRailsプラグインをインストールすることによって、Rails仕様にする感じです。

    RadRailsのインストール

    Aptanaを立ち上げて最初の画面のRadRailsインストールボタンをクリック。
    aptana.tv

    後は適当に進んでください。

    ■参考リンク
    aptana.tv

    RadRailsの設定

    RailsのPathを指定する必要があるので、
    「Window」→「Preferences」→「Rails」
    を開いて「/usr/bin/rails」と入力する。

    Preferences

    もしPathが怪しい場合は、ターミナルで
    「which rails」
    と入力してrailsのPathを表示させてみてください。

    Railsプロジェクトの作成

    「File」→「New」→「Rails Project」からRailsプロジェクトを作成する。
    これだけでいいみたい。またターミナルから「rails test」のように実行しても同じ感じに雛形コードを自動で生成してくれます。

    たったこれだけでRailsの基本となるコードが生成されサーバーも起動しているので試しにSafariなどで、http://127.0.0.1:3000/と入力すると
    「Welcome to Aptana RadRails」と表示された!!
    おお〜。なんかすごい。

    Aptana RadRails

    起動しているサーバーはRuby標準添付のWEBrickというもので、とりあえずサクッとRailsで遊んでみたい場合にはこれでよいみたい。
    これ以外にもMongrelという起動が高速なサーバーもあるがこれはダウンロードしてこないといけないっぽいから今はとりあえずWEBrickで遊んでみる。

    MySQLのインストール

    以下を見てインストールした。
    MacOSXでサーバー稼業 : Mac OS XにMySQLをインストールしよう

    MySQLをインストールしたら以下のコマンドを打つとMySQLが起動するみたいなんだけど、

    「/Library/StartupItems/MySQLCOM/MySQLCOM start」

    この後に

    「/usr/local/mysql/bin/mysql -u root」

    と打っても
    「ERROR 2002: Can't connect to local MySQL server through socket '/private/tmp/mysql.sock' (2)」
    と表示されてMySQLが立ち上がっていない感じになってしまった。
    う〜ん、何がいけないのか・・・

    ちなみにMySQLのdmgを開いたときにMySQL.prefPaneというファイルがあるのでこれをインストールしておくとわざわざターミナルからMySQLを起動しなくてもよくなる。
    今回はこれで逃げてみよう。

    mysql-5.1.24-rc-osx10.5-x86

    ■参考リンク
    素晴らしき哉、人生!: Mac OS 10.5にMySQLインストール

    phpMyAdminをインストール

    基本的なことは以下を見てインストールした。
    MacOSXでサーバー稼業 : Mac OS XにphpMyAdminをインストールしよう

    ローカルのWebServerにアクセスするためにはシステム環境設定の「共有」からWebServerを有効にする必要があるよう。
    MacOSXでサーバー稼業 : 自分のMacでホームページを公開しよう
    これをやらないで「http://localhost/」にアクセスしてたんだけど、いっこうに表示されないから少しハマった。

    さらに
    「http://localhost/phpmyadmin」
    にアクセスしてもPHPのソースコードが画面に表示されてしまったので、PHPを有効にする必要があるようだ。

    以下にその説明が書いてあります。やっぱり有効にする必要があった〜!
    MacFeeling » Blog Archive » LeopardでPHP
    「/etc/apache2/httpd.conf」→「#LoadModule php5_module libexec/apache2/libphp5.so」
    この行のコメントを外す必要があります。

    これでアクセスしてもまだエラーが表示されてしまう・・・
    どうやらphp.iniというファイルが必要なよう。
    以下のコマンドでpho.ini.defaultからコピーを作成し、ちょびっと編集。

    sudo cp /etc/php.ini.default /etc/php.ini

    "mysql.default_socket ="というところを探して次のように変更。

    mysql.default_socket = /tmp/mysql.sock
    再起動。

    via: voice over the field: Mac OS X 10.4.4でphpとMySQLの問題発生

    phpMyAdminを入れるのに一番苦労してしまった。
    手作業で値の変更するあたりがまだまだ敷居の高さが残ってるのかな。Leopardの次バージョンで全部セットしてくれたら楽なのにな〜。

    localhost / localhost | phpMyAdmin 2.11.6

    やっとこれでRailsで遊べる環境が整った。
    次でちょこちょこコードを書いていこう。

    IEとFirefoxでテキストボックス上でのEnterの挙動について

    テキストボックス上にカーソルがある場合にEnterキーを押すとSubmitが走るようになっていますが、IEとFirefoxまたinput要素なのかbutton要素なのかで結構挙動が違うのでいろいろ試してみました。

    まずテキストボックスの値ですが、これはどの場合でも正しくSubmitされていました。
    問題なのはinput要素とbutton要素でどのボタンをクリックしたかがサーバーにSubmitされるかされないかの違いがあります。
    以下でinput要素とbutton要素の場合にどういったボタン情報がSubmitされるかをまとめてみました。
    かなり個人的なメモですが、UIを意識したサイト作りには欠かせないかもしれません。
    特にサーバー側でどのボタンをクリックされたかで判定している場合は、場合によってはボタン情報がSubmitされないので予期せぬバグが潜む可能性があります。

    なお今回はFormのメソッドを指定していないので、GetとしてSubmitされます。

    input type="button"の場合

    <form>
    <input type=text name="text1" value="テキスト1" />
    <input type=submit name="input1" value="aaaaa" />
    </form>

    firefox:text1=%E3%83%86%E3%82%AD%E3%82%B9%E3%83%881&input1=aaaaa
    ie6.0:text1=%E3%83%86%E3%82%AD%E3%82%B9%E3%83%881
    ie7.0:text1=%E3%83%86%E3%82%AD%E3%82%B9%E3%83%881
    

    input type="button"(複数)の場合

    <form>
    <input type=text name="text1_1" value="テキスト1_1" />
    <input type=text name="text1_2" value="テキスト1_2" />
    <input type=submit name="input1_1" value="ddddd" />
    </form>

    firefox:text1_1=%E3%83%86%E3%82%AD%E3%82%B9%E3%83%881_1&text1_2=%E3%83%86%E3%82%AD%E3%82%B9%E3%83%881_2&input1_1=ddddd
    ie6.0:text1_1=%E3%83%86%E3%82%AD%E3%82%B9%E3%83%881_1&text1_2=%E3%83%86%E3%82%AD%E3%82%B9%E3%83%881_2&input1_1=ddddd
    ie7.0:text1_1=%E3%83%86%E3%82%AD%E3%82%B9%E3%83%881_1&text1_2=%E3%83%86%E3%82%AD%E3%82%B9%E3%83%881_2&input1_1=ddddd
    

    buttonの場合

    <form>
    <input type=text name="text2" value="テキスト2" />
    <button type=submit name="input2" value="bbbbb">ccccc</button>
    </form>

    firefox:text2=%E3%83%86%E3%82%AD%E3%82%B9%E3%83%882&input2=bbbbb
    ie6.0:text2=%E3%83%86%E3%82%AD%E3%82%B9%E3%83%882&input2=ccccc
    ie7.0:text2=%E3%83%86%E3%82%AD%E3%82%B9%E3%83%882
    

    button(複数)の場合

    <form>
    <input type=text name="text2_1" value="テキスト2_1" />
    <input type=text name="text2_2" value="テキスト2_2" />
    <button type=submit name="input2" value="eeeee">fffff</button>
    </form>

    firefox:text2_1=%E3%83%86%E3%82%AD%E3%82%B9%E3%83%882_1&text2_2=%E3%83%86%E3%82%AD%E3%82%B9%E3%83%882_2&input2=eeeee
    ie6.0:text2_1=%E3%83%86%E3%82%AD%E3%82%B9%E3%83%882_1&text2_2=%E3%83%86%E3%82%AD%E3%82%B9%E3%83%882_2&input2=fffff
    ie7.0:text2_1=%E3%83%86%E3%82%AD%E3%82%B9%E3%83%882_1&text2_2=%E3%83%86%E3%82%AD%E3%82%B9%E3%83%882_2&input2=fffff
    


    一番気持ちが悪いのはテキストボックスの個数による影響です。
    これはIE限定のようですが、テキストボックスが1個の場合にはボタン情報がSubmitされず、2個以上配置した場合にはSubmitされるようです。
    う~ん、恐ろしい・・・

    ■参考リンク
    IE6のフォームの挙動
    IE のフォームがタコい件について。

    Eclipse用プラグイン「JSEclipse」で快適JavaScript生活

    EclipseでJavaScriptのコードを書く機会が増えてきたので、便利なプラグインはないものかと探していたらありました。いい感じのが!

    AptanaのEclipseプラグイン版を本当は使いたいのですが、現在開発で使っているマシンのメモリが足らず入れられないので軽めだけど、入力補完があるやつが見つかったのでメモメモ。
    (とはいってももう開発が終わりそうなので使うのは次のプロジェクトからっぽいですw)


    JSEclipseってなあに?

    Adobeが提供しているEclipse用のJavaScriptプラグインです。
    結構軽めに動くのでAptanaで重いと感じている人にはちょうどいい感じです。

    機能は以下のとおり。(十分です!)


  • コードアシスト機能

  • これは一般的なJavaScriptの関数だけでなく、JSファイル内の関数や変数もサポートされる。また、「Dojo」「Prototype」「Spry」「YUI」「Qooxdoo」に関しては最初からサポートされている。

  • シンタックスハイライト

  • 同名変数・関数のハイライト

  • 関数の折りたたみ

  • エラーリポート

  • コードテンプレート作成機能

  • Javadoc形式のコメント

  • JSファイルの関数・変数のアウトライン表示

  • via: Adobe製、フリーのJavaScriptエディタプラグイン「JSEclipse」:CodeZine

    F3で定義位置に飛べるのが楽チン。
    あとエラーリポートも熱いですね。単なるエディターだとここまではしてくれません・・・

    JSEclipseのダウンロード

    以下Adobeのサイトからダウンロード可能です。
    Adobe Labs - JSEclipse

    ダウンロードするときにAdobeIDの取得が必要になります。
    ちょっと面倒ですが、これも使いやすいJavaScriptプラグインのためです。
    (ボクはFlexのSDKをダウンロードするときにすでにAdobeIDを取得しているのでここはスルー)

    JSEclipseをEclipseに搭載する

    ダウンロードが完了し解凍したらfeaturesフォルダとpluginsの中身をコピーしましょう。
    これで完成。
    後はEclipseを起動してね。


    ■参考リンク
    Adobe製、フリーのJavaScriptエディタプラグイン「JSEclipse」:CodeZine

    JavaScript用Unitテスト「JsUnit」を使ってみた

    JavaScriptのコーディング量が多いこともあって、次回からはJsUnitを使ってテストを自動化したいな~と考えています。
    ちょこっとした修正をしても再テストをしないといけない場合もあり、やっぱりそのあたりは自動化されていると助かる。


    JsUnitのダウンロード

    JsUnitは以下からダウンロード可能です。
    JsUnit

    Eclipse用のプラグインもあるので合わせてダウンロードしてみました。


    JsUnitを使ってみる

    1. ダウンロードした圧縮ファイルを解凍するとtestRunner.htmlというファイルがあるのでとりあえずブラウザで開いてみる。
    2. 参照ボタンをクリックしてtestsフォルダの中にあるサンプルを選ぶ。
    3. Runボタンをクリックすると?!
    4. JUnitのようにグリーンのプログレスバーが表示されたと思います

    これでなんとなく雰囲気がつかめると思います。


    Test用のファイルを作ってみる

    testsフォルダの中に適当にHTMLファイルを作成し(どれかをコピーしたほうが速いかも?)、testプレフィックスが付いているメソッドを1つ作ります。
    これはJUnit同様、テストメソッドの先頭にはtestというプレフィックスをつけないといけない感じですね。

    またscriptタグに「../app/jsUnitCore.js」というJSファイルをインクルードしていますが、これがJsUnitのコアとなるJSファイルのようです。
    これをインクルードすればとりあえずOK!!


    < scriptlanguage = "JavaScript"type = "text/javascript"src = "../app/jsUnitCore.js" ></script>
    <script language="JavaScript" type="text/javascript">
    function testToJsonFired() {
    var test = "test";
    info(test);
    assertEquals("test", test);
    }
    </script>


    Eclipse用のJsUnit Pluginを入れてみる

    圧縮ファイルを解凍してできたフォルダをEclipseのPluginフォルダに放り込みます。
    Eclipseを再起動してメニューバーから「ウィンドウ」→「設定」へ。

    左のペインにJsUnitが追加されているので、ちょこっとだけ設定する。

    JsUnit installation directory:
    ここはtestRunner.htmlがあるフォルダまでのパスを設定します。
    普通ならjsunitフォルダですね。

    Browser executables:
    ここは使いたいブラウザーを設定します。
    Firefoxなら「C:\Program Files\Mozilla Firefox\firefox.exe」。

    これでOKを押して設定画面を閉じます。


    Eclipse用のJsUnit Pluginからテストしてみる

    testRunner.htmlを右クリックし実行から「JsUnit Test Page」を選択すればブラウザが起動してテストが開始されます。
    ビューからJsUnitを表示するようにしていればコンソールとかがある場所にテスト結果が表示されます。


    これ以外にもAntを使ってBuild.xmlでテストを実行する方法もあるみたいですが、どうやらボクのローカル環境ではうまく実行されなかったので今のところは無視。
    でも便利そうだから実際の開発に入ったらAntを使ったほうがよいでしょうね。


    JavaScripのUnitテストの必要性は今後高まってくるとは思いますが、結局2倍分のソースコードを書かないといけないのはやっぱり手間ですね。
    とはいっても自動化のメリットも大きい・・・う~ん。

    ■参考URL
    JsUnit を使った JavaScript のユニットテスト - WebOS Goodies
    Javascript/JsUnit - Bobchin's Wiki

    prototype.jsのInsertionオブジェクトを使うと簡単に要素に値を挿入できる

    prototype.jsのInsertionオブジェクトを使うと出力したい文字をElementオブジェクトの前とか後ろとかに自由に挿入できる。

    Insertion.Top(Elementオブジェクトの最初に値を追加したい場合)

    <div id="div1">あああ</div>
    

    <div id="div1">いいいあああ</div>
    

    にしたい場合は

    new Insertion.Top("div1"," いいい");
    


    Insertion.Bottom(Elementオブジェクトの末尾に値を追加したい場合)

    <div id="div1">あああ</div>
    

    <div id="div1">あああいいい</div>
    

    にしたい場合は

    new Insertion.Bottom("div1"," いいい");
    

    これは結構使えそうです。
    例えばGoogle Readerのようにある一定の場所までスクロールしたときに、AjaxでFeedを追加読み込みしたい場合はInsertion.Bottomで末尾に追加しちゃえばいい感じ。


    Insertion.After(Elementオブジェクト終了タグの直後に値を追加したい場合)

    <div id="div1">あああ</div>
    

    <div id="div1">あああ</div>いいい
    

    にしたい場合は

    new Insertion.After("div1"," いいい");
    


    Insertion.Before(Elementオブジェクト開始タグの直前に値を追加したい場合)

    <div id="div1">あああ</div>
    

    いいい<div id="div1">あああ</div>
    

    にしたい場合は

    new Insertion.Before("div1"," いいい");
    

    続きでprototype.jsのどのあたりに上記内容が記述されているかを解説しています。

    Continue reading

    jQueryのtoggleメソッドって気持ちいい

    jQueryのtoggleメソッドはElementをフェードアウト、フェードインする感じでなんかかわいらしい。

    しかもこれを実現しているのは、たったのこれだけ。

    $("#f").toggle("slow");
    


    以下サンプルソースコード。

    <script  type="text/javascript" src="http://hisasann.com/housetect/js/jquery.js"></script>
    <script type="text/javascript">
        function func(){
            $("#fade").toggle("slow");
        }
    </script>
    <div id="fade" style="border:1px dotted #888888;width:200px;height:50px;">
    	少しづつフェードアウトするよ
    </div>
    <button onclick="func();">toggle</button>
    

    動きは続きからどうぞ。

    Continue reading

    Aptana Eclipseプラグインを入れてみた


    Aptana単体でも使えますが、Java開発者がクライアントサイドのコーディングをする際にとっても便利そうなので、Eclipse用のプラグインをインストールしてみました。


    こちらに手順が書いてあります。
    Plugging Aptana into an existing Eclipse configuration - Aptana

    Eclipse上のヘルプからプラグインの新規検索を選んで以下を入力すればOK。
    http://update.aptana.com/install/studio/3.2/
    後はひたすらダウンロードを待つだけ(結構時間が掛かります)

    ただバージョンが3.2となっていますが、ボクが実験的に使っているEclipseは最新の3.3・・・
    大丈夫なんだろうか。

    まぁHTMLとかJavaScriptのエディターが使えればいいのでたぶん大丈夫だろう!

    またRadRailsはEclipseのプラグインとしてではなく単体で使っています。
    EclipseはJava用でRadRailsはRails専用のIDE。

    とはいってもRailsの勉強は一向に進んでいないのが現状ですw

    MySQLのストアドプロシージャでループしてみた

    OracleのPL/SQLでストアドプロシージャを書いたことはあったのですが、MySQLでの文法が分からなかったので簡単なSQLを書いてみた。

    内容は大量にデータを作りたい場合に有効なInsertのループとそれを削除するためのDeleteのループです。

    Insert文をループするストアドプロシージャ

    create procedure insertEmp()
    reads sql data
    modifies sql data
    begin
      declare counter int;
      set counter = 0;
      while counter < 100 do
        insert into
    		EMPLOYEE
    	(
    		EMPLOYEE_ID
    	)
        values
    	(
    		counter
    	);
        set counter = counter + 1;
      end while;
    end
    


    Delete文をループするストアドプロシージャ

    create procedure deleteEmp()
    reads sql data
    modifies sql data
    begin
      declare counter int;
      set counter = 0;
      while counter < 100 do
        delete from
    		EMPLOYEE
    	where
    		EMPLOYEE_ID = counter;
        set counter = counter + 1;
      end while;
    end
    

    続きでPL/SQLで書いた場合のSQLを載せておきます。
    結構文法が違うんですよね。う~~ん。
    あんまりストアドプロシージャを作る機会がなかったので、チャンスがあれば勉強していこうと思います。

    またNavicatというMySQL用のツールでGUIからストアドプロシージャを作ろうとしたのですが、以下のエラーが出て作成できなかったので、CUI上で作成したらうまくいきました。

    MySQL Error

    あんまりネットで調べてみても解決策がなかったです・・・
    ストアドプロシージャ作成時のエラーについて -OKWave

    ■関連リンク
    @IT:エンタープライズ市場に向かうMySQL 5.0[後編](1/3)

    Continue reading

    ロボットの進化が見れるBoston Dynamics Big Dogの動き

    なんだこの動きは!
    ちょっと人間の足っぽいところが気持ち悪いw

    蹴っ飛ばされてもバランスを保とうとするのは本当にすごい。
    ASIMO・・・ガンバっ!

    JavaScriptで作られたスーパーマリオ

    JavaScriptで作られたスーパーマリオ

    こりゃすごい!
    たった14KBしかないJavaScriptコードでスーパーマリオができちゃうんだもう。

    画像もCanvasというライブラリを使ってできているそうです。
    キーボードの十字キーでジャンプしたり移動できるので操作は簡単ですが、ソースコードはなかなかなボリューム。

    ソースコード

    さぁて時間のあるときにでも追ってみますか。

    Javascript Mario (音なし)
    Javascript Mario (音あり)

    [via]
    HiroIro

    ■関連リンク
    JavaScriptで図形を描くHTML要素「Canvas」の実例 - GIGAZINE

    Eclipseでエディターを最大化する人に便利なショートカット

    Eclipse 3.2

    ボクは前まではEclipseを最大化していて左側にパッケージ・エクスプローラーを表示し、右側にエディターを表示していたがこれだと画面全体をEclipseが占めてしまうしちょっと窮屈な感じがしていた。

    そこでEclipse自体は画面の3分の2くらいにしておいて、各ビューを最大化したりして切り替えるようにしている。
    これで大分画面の節約になり、キーボードの操作だけで実現できるのでありがたい。

    最大化する際のショートカットは以下の通り。

    1. Alt + -(ハイフン)
    2. X

    これでフォーカスがエディターにいる場合には、エディター部分が最大化される。

    逆に戻す場合は、

    1. Alt + -(ハイフン)
    2. R

    これで復元が可能だ。

    こんな操作だけでも結構快適になるから画面を最大化していない人には使い勝手が良いショートカットなのではないだろうか。

    Eclipseでエディターをアクティブにするショートカット

    Eclipse 3.2

    単純にF12キーを押すだけでエディター部分がアクティブになる。
    これをEclipseでファイル数が膨大のときに使えるショートカットで紹介したショートカットと合わせるととっても便利になる。

    • F12
    「Ctrl + F7」でビューを切り替えて、コンソールでも眺めたらF12でエディターに戻る。

    かなり軽快に動けそうだ!

    Eclipseでパースペクティブを切り替えるショートカット

    Eclipse 3.2

    デバッグやらチーム同期化などのパースペクティブを開きたいときにマウスでEclipseの右上まで移動して、切り替えるのが面倒だったのでいろいろ触っていたら以下の方法を発見した。

    • Ctrl + F8

    これでちょびっとEclipseでの作業が快適になった。

    location.reloadはhref属性で使うと処理が完了するまで待ちになる

    まずlocation.reloadとは

    locationオブジェクトのreloadメソッドは、現在表示されているページのリロード(再読み込み)を行います。

    Internet Explorer等の一般的なブラウザの[更新]ボタンを押したときと同じ動作です。

    via: location.reload()-JavaScriptリファレンス

    となっているので、呼び出されたタイミングで画面がリロードされるのが普通だろう。

    だがアンカータグのhrefにlocation.reloadがある場合、
    すべての処理が終わるまでリロードは待ちの状態になる。

    Continue reading

    IE Developer Toolbarが誤動作したブラウザ環境

    IEのほうでFirefoxの便利プラグインFirebug同様の機能を持つInternet Explorer Developer Toolbarをインストールしてみたのですが、うまく動作しなかったのでその環境をメモメモ。

    Internet Explorer Developer Toolbarを入れる前のブラウザ環境

    • IE6.0 SP2
    • IE7.0 スタンドアローン版/li>
    • Netscape7.1
    • Safari3.0.4
    • Opera9.25
    • Firefox1.5
    • Firefox2.0(Firebug付き)

    このブラウザ環境でInternet Explorer Developer Toolbarをインストールしたところ、IE6.0の立ち上げのときにエラーが表示される。
    ここまではよいのだが、アドレスにURLを入れてEnterを押すとなぜかFirefox2.0が起動し、お気に入りからさイトを選択してもFirefox2.0が起動した。

    もしかしたらIE7.0 スタンドアローン版が悪さをしているのかもしれないが今だにさだかではない。
    IE Developer ToolbarをアンインストールしたらIE6.0が正常に動作したので間違いなくここが問題だった。

    なかなかクロスブラウザ対応は大変であります!

    一応IE Developer Toolbarは以下からダウンロード可能です。
    機能はFirebug同様レベルなので、IEでのデバッグが便利になります。とりあえずまたの機会にインストールしてみようと思います。
    Download details: Internet Explorer Developer Toolbar

    Javaで使えるfor文の種類いろいろ

    for文を使うときにどういった方法でグルグル回すか迷う場合が多々あります。
    そんなときは目的によって使い分けてもいいかもしれません。

    以下にいろいろ列挙しときます。

    まずは適当にListを作る

            List list = new ArrayList();
            list.add("1");
            list.add("2");
            list.add("3");
    

    一般的なfor文

    一番よく見るfor文のパターンです。

            for (int i=0; i<list.size(); i++){
                System.out.print(list.get(i));
            }
    

    inライクな使い方

    これが一番楽に書けますね。
    イテレータ云々を書かなくてよいのでラクチンです。

            for (String it : list){
                System.out.print(it);
            }
    

    イテレータを使った場合

    なんか一般的に見たことがある感じ。

            for (Iterator ite = list.iterator(); ite.hasNext();) {
                String str = ite.next();
                System.out.print(str);
            }
    

    ちょっとヒネクレの場合

    これは今までに見たことがありませんが、一応載せておきます。

            int i = 0;
            for (; i < list.size(); i++) {
                System.out.print(list.get(i));
            }
    

    for文ひとつとってもいろいろあって、これもまた使うシチュエーションによって技術者が選ぶ必要があります。
    まぁ最後のヒネクレfor文はレビューのときに間違えなく怒られますが・・・w

    Eclipseでファイル数が膨大のときに使えるショートカット

    リソースを開く

    ファイル数が少なくパッケージ・エクスプローラーなどから無理なくファイルを探し出せる場合はよいのですが、プロジェクトが何個も並んでどこにあったか探すのが面倒なときがあります。

    そんなときはリソースの名称を指定して探せる便利なショートカットを使ってパパッと目的のソースに出会っちゃいましょう。

    Eclipse上で「Ctrl + Shift + R」で「リソースを開く」ウィンドウが表示されるので、後は探したいファイルの名前を入力し、見つかっただんかいでキーボードの下ボタンを押してEnter!
    これでサクッと目的のソースにたどり着けます。

    Eclipseを使ってる人は結構重宝しているみたいです。

    型を開く

    ↑で紹介したリソースを開くに似ているのですが、これはファイル名ではなく型を指定して目的のソースにたどり着く方法です。

    やり方は「Ctrl + Shift + T」です。

    プロジェクトに追加しているJarの中まで見に行ってくれるので、JDKやStrutsのソースを登録している場合にはFrameworkの中までサクッと見に行けちゃいます。
    これもまた重宝しそうなショートカットですね。

    EclipseでインターフェースじゃなくImplのほうにジャンプするショートカット

    現場のエンジニアに教えてもらい、以外にも知らなかったのでメモメモ。
    Eclipseでインターフェースを使った実装はあちらこちらで行われていると思いますが、ソースを追っているときに

    「このインターフェースのメソッドの中身ってどんなだっけ?」

    といった場面によく遭遇します。
    このときにインターフェースのところでF3キーでジャンプしてもImplクラスのほうには飛んでくれずインターフェースのほうにジャンプしてしまいます。
    これだと実装は見れないので、他の方法でなんとかImplクラスを見に行く羽目になる。

    こんな面倒なことをせずに一発でジャンプできるショートカットがありました。

    たとえばこんな感じでISearchインターフェースのメソッドgetSearchStrを使っていると仮定します。

    String strRet = ISearch.getSearchStr();
    

    このときにこのメソッドの上にカーソルを合わせて

    Ctrl + T

    実装クラスの情報がピロピロっと出てきたじゃ~ありませんか!
    なんと便利な。そしてCtrl + Tって・・・こんな簡単な方法を知らないだけでえらい面倒なことをしていたと反省。

    ちなみにISearchインターフェースの上でCtrl + Tだとうまくいかないです。
    ちゃんとメソッドの上でCtrl + Tを押しましょう!

    iBatisで&Parameter&を使うときはSQLインジェクションに気をつけたい

    iBatisでSQL内にバインド変数(?)を使いたい場合は

    EMPLOYEE_ID  = #employeeId:INTEGER#
    

    と記述しますが、これとは別に任意の文字列をiBatis側に渡したい場合があります。
    例えばORDER BY句の部分は「EMPLOYEE_ID ASC」といったように文字列を渡せばすごく便利です。
    これを実現しているのが

    ORDER BY
      $orderByName$   //ここが任意の文字列になる
    

    これは$で囲われた部分に任意の文字列を出力するということになります。
    とここで↑で紹介した#employeeId:INTEGER#も$employeeId$と書いてもいいのでは?と疑問になるかもしれませんが、これはSQLインジェクションが発生する原因になってしまいます。
    SQLインジェクションとは、DBサーバーへの攻撃手法の一つでデータベース操作用の言語SQLをインジェクション(注入)するという意味です。
    例えば

    SELECT * FROM USER WHERE EMPLOYEE_ID = ?
    

    というSQLがあった場合に

    SELECT * FROM USER WHERE EMPLOYEE_ID = 1;DELETE FROM USER
    

    といったように本来はバインド変数で1だけを渡すはずがDELETE文が埋め込まれてしまう現象を言います。
    なかなか恐ろしいSQLですね…
    先ほどORDER BY句の部分で紹介した$orderByName$は単なる文字列となるので、上記SQLインジェクションが実現できてしまいます。

    ※事前にJava側でorderByNameにDELETE文を仕込んどく
    orderByName = "1;DELETE FROM USER";
    
    

    SELECT * FROM USER WHERE EMPLOYEE_ID = $orderByName$

    意外と#と$を間違えて混合してしまう場合があるので、十分に注意したいところです。

    JavaScriptでthisキーワードはどこを参照しているの?

    JavaScriptのcalleeプロパティは関数オブジェクトを返すよの続きです。
    「arguments.callee」で関数オブジェクトを取得する方法は分かったのですが、これに「this」をつけて「this.arguments.callee」とした場合はどうなるのか試してみました。

    thisは本来カレントオブジェクトを指定する演算子になるので、一般的には

     var obj = new Object();
     obj.func = function(){}
     obj.func();

    で赤くなっている部分のオブジェクトを参照しています。
    一見thisはfunc関数自体を保持しているように見えますが、実際にはobjというオブジェクトを参照しています。
    なので、

     var obj = new Object();
     obj.func = function(){
      alert(this.arguments.callee);
     }
     obj.func();

    と参照してもthisの部分でエラーになってしまいます。
    これはthisで指定したオブジェクトはobjになるので、objオブジェクトがargumentsオブジェクトを保持していないのが原因です。
    argumentsオブジェクトは関数情報を保持しているCall(Activation)オブジェクトが持っているので、thisであるobjにはないオブジェクトになります。
    やや難しいですね。

    では以下のようにするとどうなるでしょうか。

     var func = function(){
      alert(this.arguments.callee);
     }
     func();

    この場合はthisとなるオブジェクトが存在しません。
    どこのオブジェクトにも所属していない関数はグローバルオブジェクトに所属します。

    なので、上記の場合のthisはwindowオブジェクトとなりargumentsオブジェクトを保持していないのでエラーとなる。

    なかなか複雑ですが、thisの意味あいが大分理解できたと思います。

    JavaScriptのcalleeプロパティは関数オブジェクトを返すよ

    普段あまり使われないcalleeプロパティを使ってみましたのでメモメモ。

    calleeプロパティとは

    calleeプロパティは実行中の関数オブジェクトの本体を返すプロパティです。

    と定義されているので、実行している関数のfuncitonオブジェクトが返ります。
    こんな感じです。

     function test(){
      var objCallee = test.arguments.callee;
      alert(typeof objCallee); // function
     }

    testとはこの関数自体を指し示すので、関数オブジェクトになります。
    そしてその関数の引数を保持しているargumentsオブジェクトの中にあるcalleeプロパティを呼び出している感じです。
    これで関数自体を取得することが出来ます。

    関数自体以外にもtoString()することにより関数の中身を文字列として取得することも可能です。

     function test(){
      var strCallee = test.arguments.callee.toString();
      alert(typeof strCallee); // string
     }


    また「arguments.callee.name」というnameプロパティから関数名を取得することが出来ます。
    上記例の場合は、「test」が返ってきます。
    これはJavaScriptレベルでのロギングとかで役に立ちそうです。

    Eclipseがフルスクリーンになるプラグイン

    Eclipseがフルスクリーンになるプラグイン

    Javaを使ったエンジニアは頻繁にEclipseでコーディングすることになると思いますが、Eclipseにはいろいろなウィンドウがあり、少しでも画面を大きく使いたいと思うのが普通のことだと思います。
    最近ボクはEclipseの画面を全画面にせずにソースの部分だけを残してあとのウィンドウは全部見えない状態にしたりしているが、これだとパッケージエクスプローラーを毎回表示したりと面倒。

    今回使ってみたのはEclipseの画面をフルスクリーンにするプラグイン。
    フルスクリーンとはタスクバーすら隠してしまうブラウザとかに標準搭載されているあの機能である。
    ほんの少しかもしれないがこれでEclipseの画面が大きくなるので、本気モードでガリガリコーディングしたい人にはもってこいのプラグインではないでしょうか。

    Ctrl + Alt + Z」で全画面に、「Esc」で解除といった感じで使うことが出来る。「Ctrl + Alt + Z」をもう一度押しても解除になるみたい。
    でもEscは以外にも押してしまいがちのキーなので、間違って押してしまいそうなのが難点だ。

    以下のサイトのDownloadsタブからダウンロードできます。
    eclipse-fullscreen - Google Code

    jQueryのreadyメソッドはonloadイベントより前に呼ばれる

    onloadイベントとは画像のロードもすべて完了した状態を意味するようで、これだとDOMツリーの構築は終わっているのにすごい重い画像が存在する場合はすごい時間がかかってしまうイベントです。
    最近だとAjaxで非同期に通信をするので、onloadイベントでこのAjax処理が呼ばれるように実装しているとユーザーが画面を触り始める後にonloadイベントが呼ばれてしまう場合があります。

    たとえばウノウラボ Unoh Labs: 画像の遅延読み込みで紹介されていた遅延画像読み込みを使って、その画像が必要になったタイミングで取得するようにするのもひとつの手だと思います。

    そこで今回はonloadイベントより前に実行されるDOMContentLoadedイベントなるものを調べてみました。
    このイベントはMozilla系ブラウザには搭載されているのですが、IEには搭載されていないようで自作するか外部のjsを使って実装する必要があります。まぁ自作するのもいいですが、既存であるようなのでそちらを使ったほうが勉強にもなりますね。

    外部のjsにはprototype.jsやjquery.jsがありますが、prototype.jsは1.6.0からこのイベントがサポートされています。そしてボクの今の開発環境は1.5.0・・・使えなかったです。
    なのでjquety.jsが一番妥当なのでこちらで試してみたいと思います。

    jquety.jsを使った場合はreadyメソッドを使います。documentオブジェクトを指定していますが、ここはwindowオブジェクトでもdocumentオブジェクトでも同様に動作するようです。

    <script src="jquery-1.2.1.js"></script>
    <script type="text/javascript">
    <!--

    $(document).ready(function(){
    // OnLoadイベントより前に実行される
    alert("DOMContentLoaded"); //1番目に呼ばれる
    });


    //-->
    </script>

    <body onload="alert('OnLoad');"> <!-- 2番目に呼ばれる -->

    </body>

    おお!onloadイベントより前に呼ばれています。
    DOMContentLoadedイベントをサポートしていないIEやSafariでも使えるのはすごい不思議ですね。
    これはJavaScriptでDOMツリーが構築されたタイミングをわざわざ取得しているようです。
    $(document).ready(f)、bindReady()、$.ready() 解読でかなり細かく解説されているので是非見てみてください。
    ほんとよく考えますよっ!
    このイベントのおかげでますますjquery.jsを使ってみたくなりました。

    次の開発からはjquery.jsをマネージャにごり押ししてみたいと思います。

    ■参考記事
    [ThinkIT] 第2回:jQueryライブラリの内部とonloadイベント記法 (1/2)
    $(document).ready(f)、bindReady()、$.ready() 解読
    window.onload 前でも DOM 処理が可能なら通知してくれる domready.js - METAREAL

    JavaScriptの文字列演算で+以外を使った場合

    普通JavaScriptで文字列演算をした場合は以下のように

    var strPlus = "1" + "2";
    alert(strPlus);

    として「12」がalertされますが、これを + ではなく - にしてみた場合にどうなるのでしょうか?

    では実験

    var strMinus = "1" - "2";
    alert(strMinus);

    なんと「-1」と表示されます。つまり+では文字列の連結だったのですが、-では実際の引き算が行われました。
    ふむふむ、そうなるのか~。

    ちなみに+以外の四則演算で数値文字列を計算するとこのように実際の計算が行われるようです。
    あんまり文字列同士の計算はやらないので、引き算のときにどうなる?というのを知らなかったです。お恥ずかしい・・・

    JavaScriptで角丸を実現している「Nifty Corners Cube」

    JavaScriptで角丸を実現している「Nifty Corners Cube」
    角丸の実現って結構イメージを使ってたりするかと思うんだけど、イメージを作成できないとダメだといのがちょっと残念なので、調べていたらありましたよ。
    JavaScriptからの角丸がっ!
    しかもライブラリになっているので、JSファイルのインクルードすればOK!!

    ダウンロードするとサンプルがギッシリ詰まっているので、後はまねをすれば大体のことは理解できる。
    画面でいたるところに角丸を実現するときはちょっと重いかもしれないけど、今使ってみたぶんではそこまで違和感はなかった。

    どうやって実現しているかというと、divタグの上の部分と下の部分にたくさんのbタグを付け加えて、そいつの幅を段々を細くしている感じ。
    よくある感じではありますが、JavaScriptで自動でbタグを追加してくれるので助かるといえば助かる。

    Nifty Corners Cube - freedom to round

    [via]
    てっく煮ブログ

    PeggyEditor便利機能 - キーワードチップ表示

    前回のボクの大好きなエディターはPeggyEditor - HouseTectでPeggyEditorが結構高機能ですよ~と紹介したので、今回は便利機能の一つ「キーワードチップ表示」について紹介してみます。

    キーワードチップとはコードを入力している際に、VisualStudioやeclipseのようにピロピロッとキーワード一覧を表示してくれる機能です。
    以下の写真が分かりやすいでしょう。

    PeggyEditor便利機能 - キーワードチップ表示

    これはhtmlファイルでJavaScriptを入力しているところですが、document.wrまで入力してから「Ctrl + /」を押すとそれに該当するメソッドが表示されているます。
    あとは↑ボタン押したり↓ボタン押したりで決めるときはEnterボタン!

    ちょっとカッチョいいでしょ?

    ちなみにdocumentの部分ももちろんdocくらまで入力して「Ctrl + /」を押せば補完してくれると思います。

    またこのhtmlファイルで補完して欲しいキーワードは自分で追加することが出来ます。
    あるファイルにキーワードを設定しておけば、自分オリジナルな補完も可能になります。

    キーワードを追加するファイルの場所は
    【C:\Program Files\Anchor\share\ac_web.txt】
    です。

    ここに書いてある説明とおり記述すればすぐにキーワードチップが表示されるようになります。

    たとえばボクはしょっちゅうJavaScriptのちょいプログラムを書くのですが、

    <script type="text/javascript">

    </script>

    これを毎回書くのがすごい面倒なので、「<scri」これぐらい入力したらすかさず「Ctrl + /」を押して補完しちゃっています。
    もっと言うと基本的なHTMLのテンプレートを登録しておいて、「<htm」くらいでいっきにHTMLを補完しちゃうのもかっこいいかもしれません。

    このキーワードチップ表示はいろいろな言語に対応しており、インストールした瞬間から使えるので本当に便利です。
    しかもHelp付きでキーワードチップが表示されます。今までこの機能にどんだけ助けられたことやら。

    これハマると癖になります。はい。

    ボクの大好きなエディターはPeggyEditor

    ボクの大好きなエディターはPeggyEditor
    今までいろいろなエディターを試して見ましたが、このPeggyEditorがだんとつで一位です。
    かれこれ4年近く使っていますが、他のエディターに乗り換える気がしません。

    まぁ新しいエディターがリリースされたらインストールして使ってみるのですが、自分の中ではPeggyEditorを超えるエディターに出会っていません。
    なのでちょっと便利だよ~といった機能をちょいちょい解説していきたいと思います。

    今思いつく感じだと以下のようになります。

    1. インストール時点で色設定が完了している
    2. キーボードマクロ(キーボード操作を記憶して反復処理してくれる)
    3. プロジェクトを作成できる
    4. HTML解析(これで閉じてないタグとかを発見できる)
    5. キーボードショートカットの多さ
    6. クラスやメソッドの宣言箇所に飛べる
    7. 使ってる言語のメソッド・プロパティ一覧が出る
    8. 入力する文字が付近にあればインテリセンスが出る
    9. コメント行をショートカット一発で入力できる(これ結構便利)

    ザッとこんな感じでしょうか。
    結構PeggyEditorを使っている方が回りにいなかったので、今回このようなエントリーを書いてみました。
    PeggyEditorはシェアウェアで「2500円」です。秀丸は「4200円」ですので格段にお徳かも。
    それ以外にフリーウェアとして提供されているPeggy Padというソフトもあります。
    こちらは便利な機能が省かれていますが、ボクは文章を手軽に書いたりするときに使ったりしています。

    エディターってプログラマーだけじゃなく文章を書く人にも大切なものだから自分に合うエディターを探すのは重要ですね。
    ボクももっといろんなエディター触ってみて、必要なときに必要なエディターを選べるように勉強してみようと思います。

    今回はエディターの紹介でした~。

    お試しで30日間使えるので是非この使いやすさとプログラマー向けのかゆい所に手が届く感じを味わってみてください。
    窓の杜 - Peggy

    Rubyの日本語リファレンスマニュアルで快適Ruby生活を送ろう

    RubyでコマンドラインからHelpを見る「ri」コマンドを試してみた - HouseTectでriコマンドを試したんだけど英語なのがちょっと難点だったので、日本語版のHelpを探してみました。

    あった!

    Ruby リファレンスマニュアルの Windows HTML Help版
    これです。

    HTML Help版なのでローカルにダウンロードしてからお使いください。
    ダウンロードしたファイルは「ruby-man-1.4.6-jp-htmlhelp.lzh」です。

    Helpを表示するとこんな感じです。

    ※クリックで拡大

    すげぇいい感じ。これで難なくRuby開発ができるわな。(いや、難は山積みですが・・・)

    ■参考資料
    HTML Help

    RubyでコマンドラインからHelpを見る「ri」コマンドを試してみた

    Rubyist Magazine - Ruby の歩き方より。

    ri というコマンドを使うとコマンドラインからリファレンスマニュアルを検索・表示できます。 対象のリファレンスマニュアルが英語なのが難点ですが、 Ruby 1.8 と一緒にインストールされるところが利点です。

    via: Rubyist Magazine - Ruby の歩き方

    う~ん、やっとRubyのHelpの見方が分かったんだけど英語ね。
    こうゆうときに自分が英語ができないのにすこぶる腹が立つわいな。

    でもとりあえずHelp使ってみる。以下はStringクラスのchopメソッドの説明を見た場合

    C:\>ri String.chop(違う書き方で ri String#chopでもいいらしい)

    んで以下がその説明

    ------------------------------------------------------------ String#chop
    str.chop => new_str
    ------------------------------------------------------------------------
    Returns a new +String+ with the last character removed. If the
    string ends with +\r\n+, both characters are removed. Applying
    +chop+ to an empty string returns an empty string. +String#chomp+
    is often a safer alternative, as it leaves the string unchanged if
    it doesn't end in a record separator.

    "string\r\n".chop #=> "string"
    "string\n\r".chop #=> "string\n"
    "string\n".chop #=> "string"
    "string".chop #=> "strin"
    "x".chop.chop #=> ""

    おっ、意外と読めるかも。
    「Returns a new +String+ with the last character removed」
    この部分で大体さっしは付いたけど、でも間違えて覚えてしまいそうで怖い・・・w

    日本語で手軽に見れるヘルプを探そうっと!

    GetパラメータがIEでは化けなくてFirefoxで化ける理由

    http://~で始まるURLなんですが、こちらには使用出来る文字の定めがあって、日本語が使えません。なので、ブラウザはURL中に日本語が入力されると、URLとして使って良い文字に勝手に置き換えてくれます。(InternetExploereの場合は内部で置き換えて送信しています)

    via: かとうさんの「ITアーキな日常」:イザ!

    なるほどIEは内部で置き換えて送信だからIEのアドレスバー上では、日本語は日本語のままで表示されているのねん。

    ■IE
    http://www.google.co.jp/search?hl=ja&q=あああ&lr=lang_ja

    ■Firefox
    http://www.google.co.jp/search?hl=ja&q=%82%A0%82%A0%82%A0&lr=lang_ja

    もったいないキーはもったいないから使おうよ

    3分LifeHacking:“もったいない”キーを活用する - ITmedia Biz.IDを読んで。

    “もったいない”キーとしてあまり使っていないとされるキーボードキーを他の機能に割り当てようというもの。
    そうそうあんまり使わないからね。ってちょっと待った~~。

    Continue reading

    JavaScriptではオブジェクトを日本語で記述できる?

    ECMA262-3から日本語文字での表記が可能になっているようです。
    さっそく試してみた。

    <script language="JavaScript">
    <!--

       // まずは英字
       var obj = new Object();
       obj.get = "hoge";
       alert(obj.get == obj["get"]);        // true

       // オブジェクトもプロパティも日本語
       var = new Object();
       愛.ゲットする = "大好きなあの子から";
       alert(愛.ゲットする == 愛["ゲットする"]);  // true
       // ●できたw

    //-->
    </script>

    でっ、できたよ。

    それとちょっと補足で、

    愛.ゲットする == 愛["ゲットする"]

    この表記ですが、まったく同じ意味をなしています。
    あるオブジェクトが保持しているメンバには連想配列としてアクセスできます。

    ソース解析でふたを開けてみたら、オブジェクトが日本語だったらちょっと面白いかも。
    まぁ全部書き直しになりますがねw

    超シンプルなeclipseプラグインを作ってみた

    仕事に役立つEclipseプラグインを作りたい - @ITで紹介されていたeclipseプラグインの作成をやってみた。
    とうか結構ハマってしまったので、その補足メモ。

    プラグインの開発は今までやったことがなく、誰かが作ってくれるだろうという甘えがあったので、これからちょいちょい便利そうなプラグインを作ってみたいな~とうのが今回の狙い。
    そして、まずは一番簡単なSampleを作ってみて、感覚を掴みたかったのであります。


    基本的な手順は上記URIで確認が出来るのですが、3.0のときの解説なので今回使ってみた3.2とはちょっと勝手が違うように感じました。
    最終的にプラグインプロジェクトを作っていき、plugin.xmlが以下のようになれば正解なのですが、赤字のところが抜けてしまってちょっとハマってしまいました。
    何度「Eclipseアプリケーションの起動」をやってみてもプラグインが表示されないので、プラグインの情報が書いてあるplugin.xmlを眺めていたらvisible="true"が抜けてるのを発見。
    そりゃ表示されないやっw

    <?xml version="1.0" encoding="UTF-8"?>
    <?eclipse version="3.2"?>
    <plugin>
      <extension
        point="org.eclipse.ui.actionSets">
       <actionSet
        id="HelloPlugin.actionSet1"
        label="HelloPlugin.actionSet1"
        visible="true">
        <action
          class="actions.HelloPluginAction"
          icon="icon.gif"
          id="HelloPlugin.action1"
          label="HelloPlugin.action1"
          style="push"
          toolbarPath="HelloPlugin.action1"/>
       </actionSet>
      </extension>

    </plugin>

    これは画面からの操作の場合、拡張タブの以下の場所にあります。
    trueにしないと表示されないよ。

    超シンプルなeclipseプラグインを作ってみた
    ※クリックで拡大

    んで、出来上がったプラグインが

    超シンプルなeclipseプラグインを作ってみた
    ※クリックで拡大

    じゃじゃ~~ん。
    赤い○が付いているところに、ボタンがあります。
    これをクリックすると、「Hello♪」って表示されるプラグインです。

    はい、何の意味もないプラグインですw
    でもこれが大きな大一歩だと確信しております。

    せっかく作ったので、1時間に一回ポチッとクリックしてあげようと思います。

    IoCコンテナってなあに?

    最近Spring Frameworkをいじる機会が多いんですけど、たまに聞くIoCコンテナの意味が全然分からなかった。
    ちょっと調べてみたのでそれをメモメモ。

    IoCコンテナとはInversion of Controlの略で、直訳すると「制御の反転」という意味になるよう。
    全然意味が分からないので、もうすこし人間語で・・・

    どうやら

    「Frameworkがコンポーネントを呼び出す」

    ということだそうです。

    なるほど、今までは自分たちが作成したコンポーネントがFrameworkを呼び出していたのに、IoCコンテナではFrameworkがコンポーネントを呼び出してくれる。
    そのままですねw

    つまりSpring FrameworkではXML設定ファイルにオブジェクト間の連携を記述し、そのオブジェクトの利用者は自らがNew(インスタンス生成)をしないということがこのIoCコンテナという名前の由来なんですね。
    なるほど、やっと理解ができました。

    ちなみに今はIoCコンテナという呼び方ではなくDIコンテナと呼ばれています。
    これはソフトウェア技術者のマーティン・ファウラーさんが作成した言葉だそうです。
    DIコンテナは、正式にはDependency Injection(依存性の注入)とう言葉の略で、あるオブジェクトに対して、使うオブジェクトをセットすることを意味しています。
    注入~注入~。(注入って言うと響きはいいけど、難しいよね)

    これでNewをしないでよいのですね。

    結果的にIoCコンテナとDIコンテナは一緒の意味でした。
    な~~んだ!

    prototype.jsのEvent.observeを使ってみる

    JavaScriptを使ってアプリケーションを作る場合、ユーザビリティを考えるといろいろなイベントを使うことになると思います。
    例えばボタンが押された場合や、画面が表示された場合などなど。

    このときに発生したイベントでこんな処理をしたいな~と思ったときに登録するのがイベントハンドラ(関数)です。

    <input type="button" onclick="ajaxRequest();"/>

    でもこれだとデザインとロジックの分離といった考えから外れて、ちょっとHTML自体が見にくくなってしまう場合があります。
    そこで登場するのがJavaScriptからイベントを登録するといった考え方です。

    「なんか難しそうだな~」または「面倒だな~」と思われるかもしれませんが、なんてことはありません。
    1個のメソッドを呼ぶだけでいいんです。ラクチン!

    それがprototype.jsに定義されているEventクラスのobserveメソッドです。

    使い方はいたってシンプルで

    <script language="JavaScript">
    <!--

       // こんな感じでイベントを登録できる
       // Event.observeはブラウザ毎の登録の違いを吸収してくれるよ
       Event.observe(window, 'unload', function(){
         alert("a");
       });

    //-->
    </script>

    このように

    1. イベントを追加したいオブジェクト:「window」
    2. どのイベントに追加するか?:「unload」
    3. あとイベントハンドラ

    を引数で渡すだけです。

    上記では無名関数をそのまま入れています。

    これで画面のonload時に上記処理を呼び出してで目的のイベントを登録しといたら、なんだかカッチョイイですね!
    今まであんまり使ったことはなかったのですが、これから進んで使ってみようと思います。

    ちなみにどうしてこのようにわざわざprototype.jsのEvent.observeを使わないといけないかと言うと、ブラウザ毎にイベントを追加するメソッドが違うからです。
    Internet Explorerでは

    attachEvent, detachEvent

    Firefox,Opera,Safariでは

    addEventListener, removeEventListener

    ほんのちょびっと違いますねw
    これをEvent.observeが吸収してくれているのです。(なんかいいヤツだな~)
    デザインと処理の分離で、見やすいコード+デザイナーさんに優しい設計をしてみてはいかがでしょうか。

    プロジェクト管理ツールっていっぱいあるな~

    BTS というものを使ってみよう - にぽたん研究所を読んでて、BTSって使ったことないな~と思ったのでさっそくググったら。
    ウィキペディアにプロジェクト管理のツールが載ってたのでメモ。



    主なバグ管理システム



    • Bugzilla – 元々Netscape社が社内で使用していたが、後に公開された。

    • mantis – PHP、Webサーバ(apache、IIS)、MySQLがあれば、Windows、OS/2、MacOS、Unix互換OSで動く。

    • 影舞 – 日本で開発されたバグ管理システムで、日本語に完全対応している。

    • Trac – バグ管理システムの他にコミュニケーション支援としてのウィキリポジトリブラウザの機能を備えている。

    • Scarab - 高いカスタマイズ能力を持ち、表示属性や表示順などの設定をGUIにて行える。

    • Papilio – サーバ構築不要。接続している各端末がお互いに同期してデータを共有。

    • JIRA (ソフトウェア)

    • redMine - Ruby on Railsで書かれたバグトラッキングシステム。標準でWikiとガントチャートが付き、複数のプロジェクトを管理できる。

    • Backlog - 日本で開発されたASP型のプロジェクト管理ツール。バグ・タスク管理、ウィキSubversionホスティング、WebDAVファイル管理など統合的に管理ができる。

    • BugLister - Windows用のバグ管理ツール。Access のデータ構造でデータを持ち、Excel や Word との連携もする。

    • Microsoft Team Foundation Server (TFS) - ソースコードリポジトリであるMicrosoft Visual SourceSafeやドキュメント管理サーバであるMicrosoft SharePoint Serverと統合されており、Microsoft Visual Studioから利用することができるため、.net系の大規模プロジェクトで活用されることが多い。


    via: バグ管理システム - Wikipedia

    BugzillaとTracは使ったことがあるが、それ以外はさっぱり・・・
    ローカルに入れてみるのもいいかもしれない。

    それとにぽたんさんが作られたタスク共有ツールの決定版 - fixdapも紹介されていたので、今後使ってみようと思う。

    JScriptの@cc_onを使ってみよう

    Clouder::Blogger: @cc_on ってなに?@cc_onが紹介されていたのでボクもやってみた。

    @cc_onとは、

    @cc_on ステートメントを記述すると、スクリプト エンジンで条件コンパイルが行われるようになります。

    @cc_on ステートメントは、コメントの中に記述するようにします。この場合、条件コンパイルをサポートしていないブラウザでも、構文エラーが発生しません。次にそのコード例を示します。

    /*@cc_on*/
    // The remainder of the script.

    @if ステートメントまたは @set ステートメントをコメント外に記述することでも、条件コンパイルをアクティブにできます。

    via: @cc_on ステートメント

    条件コンパイルを可能にするスイッチみたいなもんで、これはC言語でいうところのプリプロセッサといった感じかな?

    以下に書いたコードをHTMLとして実行すると、IE限定で@cc_onが効いた処理が動く。

    <html>
    <body>
    <script type="text/javascript">
       // IEだとHello, JScript!と表示される
       /*@cc_on document.write("Hello, JScript!"); @*/

       // IE6だとJScript Version 5.0 or better.と表示され
       // FirefoxだとYou need a more recent script engine.が表示される
       /*@cc_on @*/
       /*@if (@_jscript_version >= 5)
         document.write("JScript Version 5.0 or better.<BR>");
        @else @*/
         document.write("You need a more recent script engine.<BR>");
       /*@end @*/
    </script>
    </body>
    </html>

    う~ん、なるほど。これはこれで面白い。
    仕事で使うチャンスがあるかどうかは分からないけど、まめ知識にはもってこいだな。

    上記ソースだとほとんどの行がコメントなので、かなり見にくいがJScript限定で遊べる代物だからちょびっとソースに忍ばせても楽しいかも。
    (バグらない程度にねっ!)

    amachangさんのところで一行で IE の JavaScript を高速化する方法 - IT戦記として紹介されていたので、こちらも参考にしてみてください。

    とここまで書いてもIE限定・・・

    無名関数、クロージャ、そしてレキシカルスコープへ

    Life is beautiful: Javascript、クロージャを使ったプライベート関数の隠蔽についてを読んで。

    JavaScriptで無名関数はちょくちょく出てくるんだけど、クロージャは一見するとなかなかの曲者。
    説明としては、

    親関数の外に参照が渡される内部関数をクロージャと呼ぶ

    via: JavaScript クロージャとレキシカルスコープ - Backstage of theater.js

    ふむふむ、なかなか難しいな。
    では、Life is beautiful: Javascript、クロージャを使ったプライベート関数の隠蔽についてで紹介されていた内容と照らし合わせてみよう。

    以下のソースを見てください。

    <script language="JavaScript">
    <!--

    var code2name = (function(){
      var mapping = {
        'us': 'United States',
        'ja': 'Japan',
        'ko': 'Korea',
        'ru': 'Russa',
        'uk': 'United Kingdom',
        'fr': 'France',
        'cc': 'China',
        'gw': 'Germany'
      };
      return function(code) { return mapping[code] || '(unknown)';};
    })();

    document.writeln(code2name('us'));    // United Statesと出力

    //-->
    </script>

    ちょっとソースは引用元より修正してありますが、ほとんど同じです。
    実行すると「United States」と出力されるので、うまくマッピング処理がされているようだ。

    では一旦クロージャの話の前に、気になるところを説明します。

    それは・・・

    <script language="JavaScript">
    <!--

    var code2name = (function(){
      var mapping = {
        'us': 'United States',
        'ja': 'Japan',
        'ko': 'Korea',
        'ru': 'Russa',
        'uk': 'United Kingdom',
        'fr': 'France',
        'cc': 'China',
        'gw': 'Germany'
      };
      return function(code) { return mapping[code] || '(unknown)';};
    })();    ←*1 これ!

    document.writeln(code2name('us'));    // United Statesと出力

    //-->
    </script>

    *1  ここのカッコ()でその直前に定義した無名関数を実行する。

    赤字のところ!
    なんじゃこりゃ??

    いやいや、大丈夫です。手順を踏めば簡単に理解ができます。
    これは(function ~~)で囲われた無名関数を()で実行し、その結果を返すといった感じです。
    つまり「code2name」に入るオブジェクトはreturn functionから始まる無名関数。
    一番外側にある無名関数ではないのでそこが注意ポイントです。

    これがクロージャの定義:「親関数の外に参照が渡される内部関数をクロージャと呼ぶ」にあたるのですね。

    ではでは、↑の処理をもう少し分解して書き換えてみましょう。

    <script language="JavaScript">
    <!--

    var code2name = function(){
      var mapping = {
        'us': 'United States',
        'ja': 'Japan',
        'ko': 'Korea',
        'ru': 'Russa',
        'uk': 'United Kingdom',
        'fr': 'France',
        'cc': 'China',
        'gw': 'Germany'
      };
      return function(code) { return mapping[code] || '(unknown)';};
    };    ←*1

    var method = code2name();
    method('ko');

    //-->
    </script>

    *1  今度はカッコがありません。

    これでも同様な結果になります。

    (function ~~)()で事前に無名関数を実行していないので、一旦クロージャオブジェクトを取得する必要があります。
    そして取得したクロージャオブジェクトを実行すれば同様の結果になる。
    つまりこの部分です

    var method = code2name();   // 一旦オブジェクトを取得する

    う~ん、どっちのほうが分かりやすいんだろう。

    一旦変数に入れる手間が大きいから(function ~~)()で事前に実行しておいたほうが良いかもしれないですね。

    ■クロージャを使う利点
    Life is beautiful: Javascript、クロージャを使ったプライベート関数の隠蔽についてでも解説されていますが、↑のソースでmapping変数がありますが、これは不変的な連想配列なので1回作成すればよいものと考えます。
    つまり一番外側の無名関数の中に隠蔽することによって、Javaでいうstaticなメンバの扱いになります。これはオーバヘッドが少なくてすむのできっちりメモリを意識したい人にはいいですね。
    そしてクロージャの中でmapping変数が参照されているので、ガーベジコレクタがオブジェクトを破棄せずに残しててくれます。

    これがレキシカルスコープですね。
    レキシカルスコープの説明についてはJavaScript クロージャとレキシカルスコープこちらがとっても分かりやすかったです。

    便利で面白いですが、ちょっぴり難しくなってしまうのは難点です。

    Rubyでのコンソール出力メソッドいろいろ

    なんかいろいろ種類があったので試してみました。
    ちょっとしたプログラムを作るときに重宝するので、今後頻繁に使いそうです。

    Rubyでのコンソール出力メソッド
    「putsメソッド」や「printメソッド」はオブジェクトを文字に変換して出力する基本的なメソッドです。

    一方ちょっと特殊な「pメソッド」は、オブジェクトの内部状態を出力します。
    なので、ちょいプログラムを作ってテストするときは文字数が少ないputsメソッドを使うのがよいのかな?w

    でも改行されてしまうので、文字連結とかで改行してほしくないときはprintメソッドを使えばよいのでしょう。

    printfメソッドにこの場合配列のobjをそのまま渡すとエラーになってしまいます。
    Cと同じように書けば普通に動く。
    printf("Line:%d %d %d\n",obj[0], obj[1], obj[2])
    こんな感じね。

    以下出力結果。
    alt=
    pメソッドがobj = [1, 2, 3]で指定した右側がそっくり出力されています。
    ほほ~う。これは使えるかもしれない。

    さらにppメソッドなるものがあるようですが、それはまた次回調べてみます。

    なかなか奥が深いっす。Rubyちゃん。

    Windows VistaでTomcatを起動した場合エラーが出る件

    ちょっと前にハマってしまったWindows VistaにTomcatをインストールして、その後Tomcatを起動しようとすると以下のエラーが出て、一向にTomcatが立ち上がらない現象。

    java.io.IOException: 元のファイル名をC:\Program Files\Apache Software Foundation\Tomcat 5.5\conf\tomcat-users.xml.oldに変更できません

    どうやらWindows Vistaには新しいユーザ管理の制限があり、そいつが悪さ?をしているみたい。
    それがUACだ。

    管理者でも制限ユーザーになるUAC

     User Account Control(UAC)とは,管理者権限が与えられたアカウントの権限を恒常的に制限する機能だ。スタート・メニューの[All Programs]−[Turn UAP Settings On or Off]から設定する。

     UACが有効になっていると,管理者であっても制限ユーザー相当の権限しか使えなくなる。コントロール・パネルやレジストリの操作など本来管理者権限が必要な作業をする際は,現在ログオンしている管理者アカウントのパスワードの再入力が求められる。認証が成功すると,その操作のときだけ完全な管理者権限が利用できるようになる

    via: (第2回)管理者権限も制限されるWindows Vistaの新しいセキュリティ:ITpro

    基本的にインストールをしようとしたり、削除したりしようとすると毎回確認ダイアログが出てしまうんだね。
    これは今までのWindowsユーザーからするとちょっとうざいかも。

    というのもTomcat起動時にはいろんな実行ファイルが読み込まれるので、いったいどの実行ファイルに権限を与えればいいかわかりにくいからだ。

    なので、このUACのユーザーアカウントの制御をはずして実行したらうまくいった。

    ■UACの無効化
    ・コントロール・パネルの[ユーザーアカウント]を開くと、下のほうに[ユーザーアカウント制御の有効化または無効化]というのがあるのでクリック。
    ・初めはチェックが入ってると思うので、チェックを外す。
    ・これでUACを無効化した感じだ。(再起動が必要)

    なんとも親切だが、よりいっそうコンピューターを使う人の敷居を上げた感じは否めない。
    セキュリティ的に強くなったのは分かるんだけどね・・・w

    ■関連ツール
    Windows Vistaの“UAC”による権限昇格を一度で済ませるアプリ起動支援ツール

    spring2.0のautowire属性が激しく便利

    sprign2.0からautowiringという機能が追加されたようで、いろいろ試してみたけどこれはいいっす!
    今までは以下のようにrefを指定してきっちり参照用のbeanを記述してたけど、どうやらそんなのも
    いらず、勝手にインジェクションしてくれる。

    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN"
    "http://www.springframework.org/dtd/spring-beans.dtd">
    <beans>
     <bean id="bar" class="example.autowiring.Bar">
      <property name="hoge">
       <ref local="hoge"/>
      </property>
     </bean>
     <bean id="hoge"
      class="example.autowiring.Hoge">
     </bean>
    </beans>

    以下2パターンは基本的に変わらない。
    これはbarクラスの中にhogeSetterが存在しているので、勝手にインジェクションしといてよっ。springさん!
    といった記述。
    ↑の設定ファイルと比べるとかなり楽になった。

    ■これは1つのbeanに対してautowiringを実行した場合

    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN"
    "http://www.springframework.org/dtd/spring-beans.dtd">
    <beans >
     <bean id="hoge" class="example.autowiring.Hoge" />
     <bean id="bar" class="example.autowiring.Bar" autowire="byType" />
    </beans>

    ■こっちはbeans全体に対してautowiringを実行した場合

    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN"
    "http://www.springframework.org/dtd/spring-beans.dtd">
    <beans default-autowire="autodetect">
     <bean id="hoge" class="example.autowiring.Hoge" />
     <bean id="bar" class="example.autowiring.Bar" />
    </beans>

    autowireやdefault-autowireの設定できる値は以下が参考になる。
    あんまりこのことを取り上げてるサイトがなかったからすごい助かりました。
    bean要素のautowire属性 - Xenonの日記

    IEでfloatを使った場合margin-bottomが無視されてしまう

    午前中からCSSで散々悩んでようやく原因と思われる記事を発見したのでメモ。
    起業報告書のブログより引用。

    ○ float: left (IE6)
    ◆ marginに指定無し => 正常にレンダリング
    ◆ margin-left: Npx => 2Npxの左マージンになる
    ◆ margin-top/right => 正常にレンダリングされる
    ◆ margin-bottom => 値が無視される

    ○ float: right (IE)
    ◆ marginに指定無し => 正常にレンダリング
    ◆ margin-right: Npx => 2Npxの右マージンになる
    ◆ margin-top/left => 正常にレンダリングされる
    ◆ margin-bottom => 正常にレンダリングされる

    via: 起業報告書:浮動ボックスとmarginプロパティー - livedoor Blog(ブログ)

    まさか値が無視されるとはね・・・
    さぁてこれをどうやって同じにすればよいのか考えて見ます。

    Firefoxではタグに値を入れるときはinnerTextではなくtextContentを使う

    クロスブラウザ対応ではいろいろとブラウザ間でサポートされていないプロパティがあり知っていないと、「あれ?動かないぞっ!」となってしまうので、これからちょいちょいメモしていきます。

    今回はIEでは普通に使えるinnerTextプロパティがFirefoxではtextContentプロパティを使う
    です。
    innerTextプロパティはDOM経由で取得したタグオブジェクトの開始タグと終了タグの間に文字を入れる処理です。これは単純な文字列になってしまうので、HTMLタグを埋め込みたい場合は、innerHTMLプロパティを使用します。

    以下試しのコードを書いてみました。
    確かにIEとFirefoxで有効なプロパティが違いますね。

    <html>
    <head>

    <script language="JavaScript">
    <!--

      function m(){
       document.getElementById("d1").innerHTML = "<b>aaa</a>";

       if (/MSIE/.test(navigator.userAgent)){
        document.getElementById("d2").innerText = "<b>aaa</a>";
        alert("MSIE"); // 確認用アラート
       } else if (/Firefox/.test(navigator.userAgent)){
        document.getElementById("d2").textContent = "<b>aaa</a>";
        alert("Firefox"); // 確認用アラート
       }
      }

    //-->
    </script>

    </head>
    <body onload="m();">
      <div id="d1"></div>
      <div id="d2"></div>
    </body>
    </html>

    クライアントの使用しているブラウザを判定するステートメントもいろいろあるみたいなので、これから探っていってみようと思います。
    あんまり知らないもので・・・

    AjaxクラスのonCompleteメソッドを使うときに気をつけること

    最近とんと使ってなかったprototype.jsのAjaxクラスを追ってて、onCompleteメソッドを使おうと思ったんですけど、最近Ajaxから離れてたから全然忘れてたことに迷宮入りしてしまった。

    というのも

    通信が成功しても失敗しても「完了時の処理」が実行されます。

    via: Ajax汎用ライブラリ:prototype.js:通信エラー時の処理(onSuccess, onFailure)

    と記述があって、エラーだろうがなんだろうがとにかく通信が完了した場合にはonCompleteメソッドが呼び出されてしまう。
    これはイカンですな。(ボクの使い方がイカンですな)


    なので、

    new Ajax.Request("~~.do",{
      method : 'post',
      parameters : "id=" + id,
      onLoading : function(){},
      onFailure : function(){},
        alert("失敗");
      onSuccess : function(res){
        var data = eval('(' + res.responseText + ')');
        alert(data + "成功");
      },
      onComplete : function(){
      }
    });

    としてエラーの場合と成功の場合の処理を分けてみました。
    これで一応一段落。

    prototype.jsもう一度読みなおしてみます。(敷居が高い?)

    spring2.0でconfigファイルにDTDを設定しない場合のexception

    これは意外と自分でちょこっとしたspringのプログラムを作ったときにハマることかな。
    configファイルにDTDが記述されていないと、SAXParseExceptionが発生してしまう。

    この場合configファイルの一番上にある

    <?xml version="1.0" encoding="UTF-8"?>

    の1行下に以下のDTDを追加すればOKかな。

    <!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd">

    ボクはこれで回避しました。

    2007/11/21 11:41:14 org.springframework.core.CollectionFactory
    情報: JDK 1.4+ collections available
    2007/11/21 11:41:14 org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions
    情報: Loading XML bean definitions from file [C:\mycom\workspace\springAutowire\config\autowiring.xml]
    Exception in thread "main" org.springframework.beans.factory.BeanDefinitionStoreException: Line 2 in XML document from file [C:\mycom\workspace\springAutowire\config\autowiring.xml] is invalid; nested exception is org.xml.sax.SAXParseException: cvc-elt.1: Cannot find the declaration of element 'beans'.
    Caused by: org.xml.sax.SAXParseException: cvc-elt.1: Cannot find the declaration of element 'beans'.
    at com.sun.org.apache.xerces.internal.util.ErrorHandlerWrapper.createSAXParseException(Unknown Source)
    at com.sun.org.apache.xerces.internal.util.ErrorHandlerWrapper.error(Unknown Source)
    at com.sun.org.apache.xerces.internal.impl.XMLErrorReporter.reportError(Unknown Source)
    at com.sun.org.apache.xerces.internal.impl.XMLErrorReporter.reportError(Unknown Source)
    at com.sun.org.apache.xerces.internal.impl.xs.XMLSchemaValidator.handleStartElement(Unknown Source)
    at com.sun.org.apache.xerces.internal.impl.xs.XMLSchemaValidator.startElement(Unknown Source)
    at com.sun.org.apache.xerces.internal.impl.XMLNSDocumentScannerImpl.scanStartElement(Unknown Source)
    at com.sun.org.apache.xerces.internal.impl.XMLNSDocumentScannerImpl$NSContentDispatcher.scanRootElementHook(Unknown Source)
    at com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl$FragmentContentDispatcher.dispatch(Unknown Source)
    at com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl.scanDocument(Unknown Source)
    at com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(Unknown Source)
    at com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(Unknown Source)
    at com.sun.org.apache.xerces.internal.parsers.XMLParser.parse(Unknown Source)
    at com.sun.org.apache.xerces.internal.parsers.DOMParser.parse(Unknown Source)
    at com.sun.org.apache.xerces.internal.jaxp.DocumentBuilderImpl.parse(Unknown Source)
    at org.springframework.beans.factory.xml.DefaultDocumentLoader.loadDocument(DefaultDocumentLoader.java:77)
    at org.springframework.beans.factory.xml.XmlBeanDefinitionReader.doLoadBeanDefinitions(XmlBeanDefinitionReader.java:405)
    at org.springframework.beans.factory.xml.XmlBeanDefinitionReader.loadBeanDefinitions(XmlBeanDefinitionReader.java:357)
    at org.springframework.beans.factory.xml.XmlBeanDefinitionReader.loadBeanDefinitions(XmlBeanDefinitionReader.java:334)
    at org.springframework.beans.factory.xml.XmlBeanFactory.(XmlBeanFactory.java:73)
    at org.springframework.beans.factory.xml.XmlBeanFactory.(XmlBeanFactory.java:61)
    at example.autowiring.Main.main(Main.java:14)

    spring2.0でconfigファイルのパースに失敗する場合のexception

    よく参考資料をネットからコピペしてxmlを指定する場合、まちがって>とか<が全角の場合がある。
    これでそのまま実行するとSAXParseExceptionが出るんだけど、
    一見わかりにくいがきっちり「Line 1 in XML document ~」と1行目がダメですよってエラーになっているから親切ですね。

    それにBeanDefinitionStoreExceptionが発生しているので、Definition(定義)が悪いとも言っている。

    単純にxmlがおかしいだけのお話。

    2007/11/21 11:26:25 org.springframework.core.CollectionFactory
    情報: JDK 1.4+ collections available
    2007/11/21 11:26:25 org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions
    情報: Loading XML bean definitions from file [C:\mycom\workspace\springAutowire\config\autowiring.xml]
    Exception in thread "main" org.springframework.beans.factory.BeanDefinitionStoreException: Line 1 in XML document from file [C:\mycom\workspace\springAutowire\config\autowiring.xml] is invalid; nested exception is org.xml.sax.SAXParseException: Content is not allowed in prolog.
    Caused by: org.xml.sax.SAXParseException: Content is not allowed in prolog.
    at com.sun.org.apache.xerces.internal.util.ErrorHandlerWrapper.createSAXParseException(Unknown Source)
    at com.sun.org.apache.xerces.internal.util.ErrorHandlerWrapper.fatalError(Unknown Source)
    at com.sun.org.apache.xerces.internal.impl.XMLErrorReporter.reportError(Unknown Source)
    at com.sun.org.apache.xerces.internal.impl.XMLErrorReporter.reportError(Unknown Source)
    at com.sun.org.apache.xerces.internal.impl.XMLScanner.reportFatalError(Unknown Source)
    at com.sun.org.apache.xerces.internal.impl.XMLDocumentScannerImpl$PrologDispatcher.dispatch(Unknown Source)
    at com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl.scanDocument(Unknown Source)
    at com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(Unknown Source)
    at com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(Unknown Source)
    at com.sun.org.apache.xerces.internal.parsers.XMLParser.parse(Unknown Source)
    at com.sun.org.apache.xerces.internal.parsers.DOMParser.parse(Unknown Source)
    at com.sun.org.apache.xerces.internal.jaxp.DocumentBuilderImpl.parse(Unknown Source)
    at org.springframework.beans.factory.xml.DefaultDocumentLoader.loadDocument(DefaultDocumentLoader.java:77)
    at org.springframework.beans.factory.xml.XmlBeanDefinitionReader.doLoadBeanDefinitions(XmlBeanDefinitionReader.java:405)
    at org.springframework.beans.factory.xml.XmlBeanDefinitionReader.loadBeanDefinitions(XmlBeanDefinitionReader.java:357)
    at org.springframework.beans.factory.xml.XmlBeanDefinitionReader.loadBeanDefinitions(XmlBeanDefinitionReader.java:334)
    at org.springframework.beans.factory.xml.XmlBeanFactory.(XmlBeanFactory.java:73)
    at org.springframework.beans.factory.xml.XmlBeanFactory.(XmlBeanFactory.java:61)
    at example.autowiring.Main.main(Main.java:14)

    Windows Vistaでのコンテキストメニュー用のSendToフォルダの場所

    Windows Vistaでのコンテキストメニュー用のSendToフォルダの場所
    右クリックの「送る」にエディタのショートカットを追加しようと思ったら、SendToフォルダの場所がXPのときと違うのが発覚。

    すぐに調べたらなんてこたない。
    以下の場所にありました。

    C:\Users\【ユーザー名】\AppData\Roaming\Microsoft\Windows\SendTo

    ちなみにこのフォルダは、フォルダオプションの表示タブで
    すべてのファイルとフォルダを表示する
    にチェックを入れていないと表示されないようです。

    Windows Vistaでのコンテキストメニュー用のSendToフォルダの場所


    関係ないけど・・・

    はじめXPの名残で、AppDataフォルダの下位ではなく【ユーザー名】の下にSendToフォルダがあると思ってて、上記のフォルダオプションを指定しても出てこなかったから、以下のように保護されたフォルダも表示したら、確かに【ユーザー名】以下にSendToフォルダがあった。
    Windows Vistaでのコンテキストメニュー用のSendToフォルダの場所

    でも入ろうとしても、
    Windows Vistaでのコンテキストメニュー用のSendToフォルダの場所
    が表示されてダメだった。
    なんでじゃいっ!

    rubygemでインストールしたファイルはどこにあるの?

    RailsのインストールやflickrAPIのインストールをするときに、「gem」コマンドを使うのですがいったいのそのライブラリはどこにあるのかがすごい疑問でした。

    探してみたところ発見!

    ボクはrubyをCドライブの直下にインストールしているので、そこから以下のようにたどっていくと発見できます。
    なんだちゃんとlibフォルダの中にあるのね。

    rubygemでインストールしたファイルはどこにあるの?

    Flickr on Railsを試してみた

    はじめにflickr-rails-ajax.mov (video/quicktime オブジェクト)で紹介されているビデオを見ながらコードを書いていたのですが、いざFlickrAPIを使う処理を実行すると
    Flickr on Railsの試してみた
    このようにInvalid API Keyと出力されて無効になっているエラーが出てしまった。

    あれやこれや試そうにもまだRailsの基礎知識が弱いので、どこを触ってよいのかさっぱりわからなかった。

    ネットで調べていたところ、

    Flickr ServicesをRails(Ruby)から利用するために,今回はFlickr.rbを利用しました.このライブラリで初期値として使われているAPIkeyがエラーで使えず苦労しましたが,Flickrへの接続インスタンスの生成メソッドをオーバーライドすることで解決しました.

    via: We Ain't Seen Nothin' Yet. : Gigazinize のなかみ

    という記述があったので、FlickrAIPのinitializeメソッドをオーバーライドしてためしてみたが、うまく動かなかった。
    きっとこっちがうまくコードを書けていない理由だろう。

    そしてPutting Flickr on Rails - NetBeans IDE 6.0 Tutorialに書いてあるチュートリアルを1つ1つ丁寧に実装していったら、意外と簡単にうまくいった。
    ちょっとハマったのは途中手書きでソースを書いてしまったところがあり、そこのケアレスミスで悩んでしまった。

    Flickr on Railsの試してみた


    今回触ったファイルは以下のとおり

    • controllers/flickr_controller.rb
    • environment.rb
    • views/flickr/index.rhtml
    • views/flickr/_photo.rhtml
    • views/layouts/application.rhtml

    データベースにつなぎにいく処理がないのでModelがないんですね。

    あとFlickrのAPIはgem経由でインストールします。
    Flickr on Railsを試してみた
    いつものおきまりの魔法ですね。

    んで実行したらこんなかんじ。
    じゃじゃ~~ん。
    Flickr on Railsの試してみた

    やっとうまく表示されましたよ。

    ■参考資料
    以下の内容を見て実装してみました。丁寧に書かれているのでわかりやすかったです。
    Putting Flickr on Rails - NetBeans IDE 6.0 Tutorial

    RadRailsでRuby on Railsアプリケーションを作ってみる

    まずはRadRailsの初期設定として、
    「window → Preferences → Rails → Configuration」
    を開いてRails PathとRake Pathを設定する。
    この設定をしなくてもrailsジェネレータが使えるが一応設定しておいた

    では「File → New → Rails Project」を実行し、bookmarkプロジェクトを作成する。
    RadRailsでRuby on Railsアプリケーションを作ってみる

    この処理はコマンドプロンプトで

    rails bookmark


    でひな形を作るのと同じである。

    次にWebrickサーバーを起動してみる。
    なお今回はポートを3001で起動しているので今後のURIは3001として話を進めていく。

    そして「http://localhost:3001/」にIEからアクセスしてみると。
    RadRailsでRuby on Railsアプリケーションを作ってみる
    おお!HTTPのGetメソッドのログが出力された。
    サーバーは確かに起動しているようだ。

    それではまずはGeneratorsを使って、Modelを作っていこう。
    作るModel名はbookmarkデータベースに作成したitemsテーブルをアクセスするためにする。
    この場合テーブル名はitemsと複数形だが、作るModel名はitemと単数形なので注意する必要がある。
    RadRailsでRuby on Railsアプリケーションを作ってみる

    次はControllerを作ってみよう。
    同じくGeneratorsからcontrollerを選んでcontroller名をitemと入力しGoを実行する。
    RadRailsでRuby on Railsアプリケーションを作ってみる

    次はつなぐデータベースを指定する。
    configフォルダの直下にある「database.yml」ファイルを以下のように編集する。


    development:
     adapter: mysql
     database: bookmark
     username: root
     password:   ←もしパスワードを設定している場合は入力する。
     host: localhost


    ここでの注意は:(コロン)の後には半角スペースが必要なことだ。

    この時点で「http://localhost:3001/item/」にアクセスしても以下の画面が出てしまう。
    これはコントローラーにActionを設定していないため、何も処理が実行されないからだ。
    RadRailsでRuby on Railsアプリケーションを作ってみる

    ではitem_controller.rbに処理を追加してみよう。
    今回はActionのコードを自動で生成してくれるscaffoldメソッドを使ってみる。
    DRY化としてCRUD操作が自動で利用可能になるよう。

    class ItemController < ApplicationController  scaffold :item end


    この処理はまだよくわかっていないので今後理解のためにエントリーにかくつもり。

    ここまで行うと、もうRailsアプリケーションの完成だ。

    さきほど試した「http://localhost:3001/item/」にアクセスすると今度は
    RadRailsでRuby on Railsアプリケーションを作ってみる
    となり、うまく動いているようだ。

    実際にレコードを追加すれば
    RadRailsでRuby on Railsアプリケーションを作ってみる
    このように1行追加されてリストが表示される。

    とりあえずはRuby on Railsを体感できた。

    これからは細かいメソッドやどうやって動いているのかを勉強していきたいと思う。
    仕事とは別にRuby on Railsを学んでいるが、実際にプロジェクトで使える日を心から待ち望みたい。

    Radrailsで快適Rails開発

    Radrailsで快適Rails開発
    Railsの開発で使うIDEを探してたら、Radrailsというeclipseと同じようなIDEを発見。

    これは使えそうだ。
    でもどうやらRailsのライブラリをインテリセンス(Ctrl+Space)で呼び出した場合に、全部のクラスがピロピロッと出てしまうようだから今後いろいろ改良が加えられていくんでしょう。

    以下を参考にしてインストールしてみました。
    aptanaダウンロード
    Aptana: Download Aptana Studio with RadRails Development Plugin

    aptanaにRadrailsプラグインを入れる方法
    aptana.tv

    MySqlをインストールしてみる

    前回、前々回のRubyをインストールしてみるRailsをインストールしてみるでRubyとRailsのインストールが完了したので、次はMySqlをインストールしてみる。

    まずはMySQL AB :: MySQL Downloadsに行ってMySqlをダウンロードしよう。

    Downloadのリンクがあるのでクリック。
    MySqlをインストールしてみる


    Windows版のミラーサイトをクリック。
    MySqlをインストールしてみる


    意外とわかりにくいけど、下のほうにある
    「» No thanks, just take me to the downloads!」をクリックする。
    MySqlをインストールしてみる

    あとはどこでもいいので国を選んでダウンロードを開始する。

    結構面倒なのね・・・

    続いてGUIで操作するためのTool「MySQL GUI Tools」をダウンロードしてみる。
    MySqlをインストールしてみる


    では実際にインストールしてみる。
    mysql-essential-5.0.45-win32.exeをクリック。
    MySqlをインストールしてみる
    ちなみに本来ならボクのマシンはAMD64のCPUを積んでいるので、Windows Essentials (AMD64 / Intel EM64T)をインストールするのかと思ったら、インストール時に「対応していません」的なエラーになりインストールできなかったので、win32のほうをインストールした。
    大丈夫かな・・・

    あとは設定画面が開いてひたすら次へ。
    1つ気をつけたのは日本語対応するために、MultiLangにチェックをつけた。

    でも1つエラー画面が出たがRetryを押したらうまくいったので良しとする。

    次にmysql-gui-tools-5.0-r12-win32をクリックしてGUI Toolsのインストール。
    こっちも次へでなんなくインストール完了。


    ではMySql Administratorでデータベースを作ってみよう。
    MySqlをインストールしてみる

    まずは新しくスキーマを作成する。画面左下のペインで右クリックし、「Create New Schema」を選ぶ。
    MySqlをインストールしてみる
    今回はBookmarkと入れてOKを押す。


    itemsテーブルを作成し、以下のようなカラムを追加した。
    MySqlをインストールしてみる
    Apply Changesを押して確定する。


    次にbmuserユーザーを作成し、先ほど作ったbookmarkスキーマに対して全権を与える。
    MySqlをインストールしてみる

    これでいよいよRailsの開発に使うベースとなるDatabaseの作成は終わった。

    なお今回はrails - masuidriveを参考にしてMySqlのインストールを行ってみた。動画でのインストール方法を見れるのは本当にありがたい。

    次で実際にRailsのアプリケーションを作ってみようと思う。

    Railsをインストールしてみる

    前回のRubyをインストールしてみるで、Rubyがインストールされたので、次はRailsのインストールをしてみる。

    RailsのインストールではRubyGemsというものを使うようだが、これはOne Click Installerで自動で入るため新たに何かをインストールする必要はない。

    さっそくRubyGemsからRailsをインストールするためのコマンドを打ってみる。
    コマンドプロンプトを開いて以下を入力する。

    gem install rails -y


    Railsをインストールしてみる
    いざEnter。

    Railsをインストールしてみる
    このRubyGemsは必要なプラグインをコマンドからダウンロード+インストールしてくれるすぐれもの。
    でも特に「Install OK!!」とかって言ってくれないのね・・・

    おそらくうまくいったのだろう。

    ではrailsの魔法を唱えてみよう。

    rails test


    Railsをインストールしてみる


    おおっ。これがテンプレートを自動で作成するrailsの魔法かっ!
    Railsをインストールしてみる
    すごい。rbファイルやrhtmlファイルやjsファイルを全自動で作ってくれてる。

    よし、ではサーバーを起動してみよう。

    ruby test/script/server


    Railsをインストールしてみる


    おお、サーバーが起動したもよう。
    なるほど、サーバーをshutdownするときはCtrl+Cを押せばいんだな。
    Railsをインストールしてみる

    では待望のURIにアクセスしてみる。
    これでうまくページが表示されればtestアプリケーションの誕生じゃあの。

    IEで以下を入力。

    http://localhost:3000


    うぉ~表示されたぞ~~。
    Strutsで初めてWelcomeが表示できたときのような感動が再び。
    Railsをインストールしてみる

    正直きもちいです。めちゃめちゃきもちいです。

    これでやっとRailsにOnした感じがしてきた。
    ただし、この時点ではコントローラーにtestが追加されていないので、URIに/test/でアクセスしても404になってしまう。
    MySqlを入れてから実際のコントロールを作ってActionにアクセスしてみよう。

    次はMySqlをインストールしてみようと思います。

    Rubyをインストールしてみる

    WindowsユーザーならInstantRailsという便利なall in oneがあるのですが、あえてそっちは使わずに1つ1つインストールしてみようと思います。

    参考にしたページは
    Rubyist Magazine - Ruby ビギナーのための CGI 入門 【第 1 回】 2 ページ

    Vistaに対応しているとは書いていなかったのですが、ダウンロードしたRubyのバージョンは
    ruby186-25.exe」にしてみた。

    Rubyをインストールしてみる
    特に何か設定せずにNextを押して進む。


    Rubyをインストールしてみる
    ふむふむ、Cドライブの直下にできるのね。解説通りのフォルダ構成ではないが特に問題なし。

    ・・・インストーラーが走ってガリガリインストールしていく。


    Rubyをインストールしてみる
    インストールが完了したよう。まだNextがあるので次へ。

    そしてFinish!!

    ではインストールが完了したかの確認をしてみよう。

    コマンドプロンプトから

    ruby -v


    と入力し、実行。

    すると
    Rubyをインストールしてみる
    おおっ、インストールしたRubyのバージョンが確認できた。

    これでRubyの勉強を進められそうだ。
    ちょっと勉強するには遅くなりすぎてしまったが、今はちょうど時間が空いているのでここでババッと概要を把握したいと思う。

    ちなみにOne Click Installerで入れると、RubyGemsも自動で入るため
    RubyGemsの説明は割愛する。

    次はRailsのインストールだっ!

    Pleiades All in One ディストリビューションで日本語化済みeclipse3.3を使う

    Pleiades All in One ディストリビューションというものがいつのまにか世に出ていて、eclipse3.3を日本語かしてくれているよう。
    なんて便利なんだ。

    Eclipse3.3(Europa)を一まとめにしたwtp-all-in-one-sdkを使ってみたで紹介したときは、まだプラグインをeclipseのpluginsフォルダにぶち込んで使っていたのに。

    ディストリビューションに含まれている内容を見るとwtp all in oneと同じ内容に思える。
    JREを含めたディストリビューションもあるので、わざわざJDKをダウンロードしなくてもよいのだろうか。

    当分はこれを使ってみようと思う。
    なおディストリビューション自体は180MBを超えているので、ダウンロードには少し時間がかかります。

    Pleiades (Eclipse プラグイン日本語化プラグイン)

    Seasar2のdiconファイルとSpringのapplicationContext.xmlを比べてみた

    一番簡単な定義として以下を書いてみた。
    greetingClientクラスのgreetingメンバにgreetingクラスをDIするパターンだ。

    こう見てみるとほとんど書き方が一緒なのが分かった。
    今はSpringでWebシステムを実装しているので設定ファイルの量が膨大だが、
    Seasar2を使えばそれも軽減されるのだろう。

    Seasar2のdiconファイル

    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE components PUBLIC
     "-//SEASAR//DTD S2Container 2.3//EN"
     "http://www.seasar.org/dtd/components23.dtd">
    <components>
     <component name="greeting"
      class="examples2.di.impl.GreetingImpl"/>
     <component name="greetingClient"
      class="examples2.di.impl.GreetingClientImpl">
       <property name="greeting">greeting</property>
     </component>
    </components>


    SpringのapplicationContext.xml

    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd">
    <beans>
     <bean id="greeting" class="examples2.di.impl.GreetingImpl" >
     </bean>
     <bean id="greetingClient" class="examples2.di.impl.GreetingClientImpl" >
      <property name="greeting" >
       <ref local="greeting"></ref>
      </property>
     </bean>
    </beans>


    またSeasar2は「Convention over Configuration(規約は設定に勝る)」を深く採用しているから
    以下の書き方でパッケージ配下のImplがサフィックスに使われているクラスのインスタンスを生成し、
    自動的にS2コンテナに登録してくれる。

    後は、S2ContainerFactoryクラスを使って取得すればいい。
    (なんて便利なんだ!)

    <component
    class="org.seasar.framework.container. autoregister.FileSystemComponentAutoRegister">
    <initMethod name="addClassPattern">
    <arg>"examples.di.impl"</arg>
    <arg>".*Impl"</arg>
    </initMethod>
    </component>

    via: Seasar - DI Container with AOP -

    追伸:
    S2StrutsなるもののExampleがSeasar2のサイトにあったので、EclipseにインポートしてみたがSaxParseExceptionが発生してTomcatの起動がうまくいかなかった。
    なんでだろう…

    Input type=file属性の入力フォームで相対パスを指定した場合submitされない

    input type="file"での最大桁数と選択したファイルがテキストボックスに反映されない場合の注意点で存在しないファイルを指定した場合にSubmitがされない現象について書きましたが、どうやら相対パスでもSubmitされないようです。

    現象

    Input type = file 属性の入力フォームに、ローカルのパス (例 : x:\aaa\bbb.txt) や、共有フォルダのパス (例 : <\\SERVER\xxxx\aaa.txt>) ではない相対パスを入力後に submit しても Web サーバーにリクエストが送信されません。

    via: [IE] Input type = file 属性の入力フォームにて submit を行っても Web サーバーから反応がない

    原因

    Windows XP Service Pack 2 のセキュリティ上の理由により、ローカルパスや共有フォルダのパスに相対パスが入力された場合には、ファイルの送信ができないよう動作が変更されております。

    via: [IE] Input type = file 属性の入力フォームにて submit を行っても Web サーバーから反応がない

    何気にWindows XP Service Pack 2でチェックされているのですね。
    知らなかった~。

    JavaのLong型の最大桁数について

    各数値クラスには便利な定数が用意されていた。
    とりあえず一通り出力してみるプログラムをメモ。

    public class maxlongvalue {
     public static void main(String[] args) {
      System.out.println(Byte.MAX_VALUE);
      System.out.println(Short.MAX_VALUE);
      System.out.println(Integer.MAX_VALUE);
      //LongのMax値
      System.out.println(Long.MAX_VALUE);
      //LongのMin値
      System.out.println(Long.MIN_VALUE);
      System.out.println(Float.MAX_VALUE);
      System.out.println(Double.MAX_VALUE);
      System.out.println(Float.POSITIVE_INFINITY);
      System.out.println(Float.NEGATIVE_INFINITY);
     }
    }

    結果はこんな感じ

      127
      32767
      2147483647
      9223372036854775807   ←ここがLongの最大値
      -9223372036854775808  ←ここがLongの最小値
      3.4028235E38
      1.7976931348623157E308
      Infinity
      -Infinity

    一応19桁近く表示可能のようだ。
    覚えておいて損はなさそう。

    ServletにおけるGETパラメータの文字化けについて

    WebブラウザからGETパラメータを送信し、それを再び自画面にResponseするような処理の場合、日本語が入ってきた場合を考慮しなければなりません。
    日本語を許容していないテキストボックスなら良いのですが、~Nameとかの場合には日本語が入ってしまいます。

    この場合単純にURLの後ろにGETパラメータを付与した状態でサーバー側に送信しても文字化けを起してしまいます。

    たとえば
    JavaScript側で


    window.open('test.do?param=' + encodeURIComponent("テスト"));

    といった感じで画面を開いて、開き先の画面でこの「テスト」を表示しようとしてもうまく表示されません。
    これはServlet側で受け取ったGETパラメータ「param」を、javax.servlet.ServletRequestクラスのgetParameterメソッドを使用して取得すると、パラメタの中身をISO-8859-1だと誤解してURLデコードしてしまうためです。

    ただし化ける現象はServletコンテナに依存していて


    たとえば,Apache JServやJakarta Tomcatは化けますが,IBMのWebSphereは化けないなどの違いが出てきます


    via: ServletとJSPにおける文字化けについて

    のようです。

    なのでGETパラメータで送られてきた日本語をHTML側でCharsetされた文字コードとして取得する必要があります。
    そこでHttpServletRequestインタフェースのsetCharacterEncodingメソッドを使って文字コードを指定すればよいのです。

    ただし、


    ※Tomcat5.xより、FORMのGETメソッドでパラメータを送信した場合、setCharacterEncodingメソッドを無視するようになりました。POSTメソッドの場合は有効です。


    GETメソッドの場合、server.xmlファイルの<connector>タグのuseBodyEncodingForURI属性をtrueに指定することで、setCharacterEncodingメソッドを有効にできます。


    via: Javaの道:Servlet(13.文字化け対策)

    とのことなので、今開発している環境がTomcat5.0なので以下の方法で実装してみました。


    if ((s = req.getParameter("s")) != null) {
    try {
    s = new String(s.getBytes("iso-8859-1"), "Shift_JIS");
    } catch (UnsupportedEncodingException e) {
    // エラー処理を記述する
    }
    }


    via: ServletとJSPにおける文字化けについて

    意外とややこしいので忘れがちになってしまいますが、テストしていくと正しく表示されないので気が付くのでしょう。

    Oracleでワイルドカードをエスケープする方法

    画面のテキストボックスからアンダースコアやパーセントが入力され、それがあいまい検索として実行される場合、ワイルドカードとしての機能を果たしてしまうのでエスケープが必要になってくる。

    画面から入力させないのが一番簡単だが・・・

    SELECT  * FROM  TABLE_A WHERE  ID like '\_%' ESCAPE '\'

    ワイルドカード文字、パーセント(%)、アンダーバー、アンダースコア(_)を LIKE で抽出条件に使用するための方法 (パーセント(%)は 0 文字以上の任意の文字列、アンダースコア(_)は 任意の 1 文字をあらわす)

    via: SELECT 文の活用(実践) - Oracle SQL 入門

    input type="file"での最大桁数と選択したファイルがテキストボックスに反映されない場合の注意点

    input type="file"を使ってファイルのアップロードを行う場合、気をつけたいのが以下の2点である。

    • IEでは254文字を超えた場合に選択したファイルがテキストボックスに反映されない
    • IEでは存在しないファイルを選択するとSubmitされない

    以下の質問では255文字となっていたのですが、255文字だとうまくいかず254文字だとうまく反映されました。

    Windows での Filename の最大長は、255文字までです。


    via: windowsでのアップロードファイル名長について - Java Solution

    Firefoxでは上記2つの注意点は当てはまらない。


    • Firefoxでは254文字を超えた場合に選択したファイルがテキストボックスに反映される

    • Firefoxでは存在しないファイルを選択してもSubmitされる

    FirefoxでのMaxlengthがあるかは現在調査中。

    ちなみに今回は、IEだけども特にinput type="file"のMaxlengthを指定せずに実装した。
    GoogleのPicasaがそうしてたから・・・笑

    ■参考資料
    クライアントスクリプトであるJavaScriptで下記のようなファイル存在確認は可能でしょうか?

    StrutsでActionを複数経由する場合の注意点

    1回のリクエストで複数のActionを経由する場合、Actionが呼ばれるたびにActionFormのSetter・Getterが呼ばれるので、1つ目のActionで設定した値が2つ目のActionで元に戻る場合がある。

    たとえば以下のようにTest1Actionが呼ばれてsuccessのときに自動的にTest2Actionが呼ばれるように実装した場合である。


     <action path="/Test1Action"
      type="Action"
      name="ActionForm"
      scope="session"
      validate="false">
       <forward name="success" path="/Test2Action.do" />
     </action>

     <action path="/Test2Action"
      type="Action"
      name="ActionForm"
      validate="false">
      validate="false">
       <forward name="success" path="test.jsp" />
     </action>

    値が元に戻ってしまうならまだ処理が落ちてしまうことはないが、例えば画面でListを持っててRequestのたびにActionFormに対してSetter・Getterが動く場合

    • Test1ActionでActionFormのListSetterが動く

    • Test1ActionのActionでListをプログラム側でnullにする

    • Test2ActionでActionFormのListSetterが値をセットしようとしてServletExceptionが発生

    たしかにnullにしたListに対してSetterが動けばそれはエラーとなってしまう。
    これは画面上にはServletExceptionがドドンと表示されるので一見何が起こっているのか分かりにくい。
    ただし、こういった内容を知っていればもしかしてあそこか?となるので開発のスループットは上がるだろう。

    実はListがnullのときにServletExceptionが発生しない方法があるが、その機能に関しては以下がとっても読みやすい。
    civic site : LazyListを使うともっと楽だった

    確かにこの方法で回避できるが、忘れてはいけないのは毎回ActionFormのSetter・Getterが動くということである。思ったとおりの値が2回目のSetterで上書きされる可能性があるので実装時には十分に考慮する必要ある。

    Eclipseでタブを移動するショートカット

    Eclipse 3.3

    Eclipseでタブを何枚も開いたときは、わざわざマウスでカチッてするのが面倒な場合があります。
    そんなときは、以下の2つの方法でタブを移動することができます。

    • Ctrl+Page Up or Page Down
    • Ctrl+F6

    どちらも有効な方法なのですが、「Ctrl+Page Up or Page Down」はXMLファイルの場合うまくいかないときがあります。
    開いたエディターによっては、1つのタブで「設計」と「ソース」というミニタブが画面下部に表示されてしまい、その中を移動してしまうからです。
    なので、タブを移動する効果的なショートカットは「Ctrl+F6」だと考えられます。

    JavaとOracleのタイムゾーンミスマッチを解消する方法

    Javaのバージョン :JDK1.4.2_08
    Oracleのバージョン :Oracle 9i

    多言語対応システムを組む際には、入力された日付を各現地時間としてDBに登録する場合がある。
    例えば画面から入力された日付をAmerica/Los_Angelesの時間として登録する場合には、


    from_tz(to_timestamp('2007/10/22 00:00', 'yyyy/mm/dd hh24:mi'), 'America/Los_Angeles')

    とfrom_tz関数を使用して現地の時間ですよ~と指定する必要がある。

    今回ボクがやろうとしたことは、
    Java側で入力した日付をUTCに変換する。
    America/Los_Angelesだとした場合には、入力された日付に対してTimeZone.getRawOffset()をすることによってUTCに変換される。

    そしてUTCに変換された日付をUTCとしてDBにInsertする。


    from_tz(to_timestamp('2007/10/22 00:00', 'yyyy/mm/dd hh24:mi'), 'Etc/GMT')

    これでうまくいくとにらんでいたのですが、以下のとおりJavaとOracleでタイムゾーンが一致しない場合がある。

    • タイムゾーンの個数の不一致

    • タイムゾーンをUTCにした場合の時間のズレ(JavaでAmerica/Los_Angelesは-8時間、OracleでAmerica/Los_Angelesは-7時間)

    これはOracle10gから解消されているようで、10gではAmerica/Los_Angelesは-8時間となっているためJavaと一致する。

    このことにより、もし多言語対応で入力された日付をUTCに変換しようとすることがある場合は極力DBのタイムゾーンに任せる方法がよいだろう。

    • 入力された日付はJava側でUTCにしない
    • from_tz関数を使って現地のローカルタイムゾーンを指定してInsertする

    これを守っておけば常にOracleのタイムゾーンを使用してInsertをかけるので、JavaとOracleのミスマッチ現象は回避できる。
    このような状況はなかなかなる機会がないと思うが、もしこのメモが誰かの役に立ったとしたらうれしいです。

    また今回Java側でUTCに変換したプログラムも公開しておく。
    基本は使わないほうがよいが、何かの参考までに。

    ■Javaで日付StringをUTCTimestampに変換する方法


     public static Timestamp getUTCTimeStamp(String date, String zone) throws ParseException{

      // 文字列型日付をTimestamp型に変換する。
      SimpleDateFormat dateFmt = new SimpleDateFormat(Constant.JAVA_DATE_FORMAT, Locale.US);


      Timestamp stamp = new Timestamp(dateFmt.parse(date).getTime());


      // 現地のタイムゾーンに設定する。
      TimeZone tz = TimeZone.getTimeZone(zone);
      dateFmt.setTimeZone(tz);


      stamp.setTime(stamp.getTime() - tz.getRawOffset());


      return stamp;
    }

    ■関連資料
    Javaの道:日付・時刻(4.TimeZoneクラス)
    Oracle Real-Time Collaborationのタイムゾーン
    Java 2 Platform SE 1.3: クラス TimeZone

    少々お待ちくださいのアニメーションGifを自作できるWebサービス

    また新しいのが出た。ローディングイメージ作成のお供に『gif generator』
    今流行のクルクル回る少々お待ちくださいアニメーションGif。
    たまに見かけますね。

    このクルクル画像を作れるジェネレータが*ホームページを作る人のネタ帳さんのところで紹介されていました。

    一般のWebシステムでもこの画像なら使えそう。
    少々お待ちくださいのアニメーションGifを自作できるWebサービス

    HTML内にハイフンがあり改行されてしまう場合の対処

    ハイフンがテーブルのカラムに入ってしまい、それを画面に出力されるときに改行されてしまうことがあったのでメモ。

    ハイフンが出力されてしまう部分の前後に

    <NOBR>~~~~ここにハイフンが来る~~~~</NOBR>

    これでそのカラムは改行されない。

    ちなみに


    <table style="table-layout:fixed;" border="1">
    <tr>
    <td style="width:100px;">
    aaaaaaaaaaaaaa-aaaaaaaaaaaaa
    </td>
    <td style="width:100px;">
    aaaaaaaaaaaaaa-aaaaaaaaaaaaa
    </td>
    </tr>
    </table>

    上記のようにstyle="table-layout:fixed;"として改行させない方法を使っても
    <NOBR>を入れないと改行されてしまう。
    Divタグのoverflowをhiddenにしたときも同じ。

    つまり改行させたくないセルが存在する場合は、必ず<NOBR>を使いましょう。

    table-layout-スタイルシートリファレンス

    ある意味ペアデバッギングでバグを発見する有効な方法


    プログラミングの光景:第1回 デバッグについてこちらでデバッグを効率よく行う方法が書かれていますが、1個面白いTipsを発見したので紹介します。



    • 身近な人に相談する(説明しているうちに自分で原因に気づく)

    これってボクは結構使う方法なのですが、相手が忙しいときはなかなか声をかけづらいもんです。
    嫌な顔されたら二度とその人に質問に行かないですもんね(笑)

    これに対して、このエントリーの著者「高林哲」氏は


    最後の,「身近な人に相談する」に関しては,状況を説明することが重要なので,相談相手は人ではなく,ぬいぐるみでもよいという説があります。


    via: プログラミングの光景:第1回 デバッグについて|gihyo.jp

    と書かれています。

    なるほど!
    でも自分の会社の社内ならまだ良いかもしれませんが、出向先でこれを実現するのは相当難しい。
    完全に変な人レッテルを貼られてしまいます。

    でも心の中でデスクに置いてあるぬいぐるみにアプローチするのはありかもしれません。(笑)
    >そこまでしなくてもという感じですが・・・

    何せ今の作業がテスト+バグ潰しなもので、これを実践してみようと企んでいます。

    ■掲載したぬいぐるみ
    ぬいぐるみ(くまのジャッキー)

    Webアプリのテストを漏れなく実施するTips

    ウノウラボ Unoh Labsさんのところで纏められてたテスト項目が非常に参考になった。

    今はテストフェーズなので、このテスト項目を元にテスト仕様書を作成してみた。
    テストは漏れなくやりたいとは、どんなITエンジニアも考えているか必ずどっかで漏れが発生してしまう。
    こういったリストを作っておくのもありなのかもしれない。

    個人的に追加したいのは、


    • 必要のない場所でスクロールバーが出現していないか?

    • 検索結果のリストは各行が途切れずに表示されるようにHeightを指定しているか?

    • ラジオボタンのラベルをクリックしても選択できるか?

    >2個目はかなり個人的ですが・・・(笑)
     スクロールバー付きのリストって、一番下の行が半分とかで途切れちゃうときが多々あるので追加。
    >3個目は適宜必要ならといったところでしょうか?

    input type="file"のボタンのCaptionを変更する方法

    input type=
    まず前提としてinput type="file"のボタンの文字を変更することは出来ない。
    そこで、それっぽいことを他の方法で実現する方法をご紹介。

    いたって単純な話だが、基本としてはinput type="file"を「visibility:hidden」で見えなくしてしまう。
    「display:none」でも良し。
    そして表向きとしてinput type="text"とinput type="button"を用意しておく。ユーザはこの表向きの部分をinput type="file"の挙動だと判断して操作することになる。

    以下のソースを見ていただければ一目瞭然だが、

    • ユーザが参照ボタンをクリックする。

    • ボタンのonclickでinput type="file"のclickメソッドを呼び出す

    • ファイルの参照画面が表示される

    • 選んだファイル名をinput type="text"のvalueにセットする

    これで一見はinput type="file"に見えるが、ボタンの文字を好きに変えることができる。
    意外と簡単ですね。

    ただこの方法は、clickメソッドをJavaScriptから呼び出しているのでIE限定です。

    <script language="JavaScript">
    <!--

    function JS_Click(){
    var file = document.getElementById("file");
    file.click();

    document.getElementById("aaa").value = file.value;
    }
    //-->
    </script>

    ■input type="file"の場合<br>
    <input type="file" value="" onclick="" id="file" />
    <br><br>
    ■input type="text"と"button"の場合<br>
    <input type="text" value="" id="aaa"> <input type="button" value="test" onclick="JS_Click();"><br>
    <input type="file" value="" onclick="" id="file" style="visibility:hidden">

    「あああ」で変換してみろwwwwwwwww

    なんでもいいがテキストエディタなどで、「あああ」と入力しスペースキーを押すとなんと「ああ」となって1個欠けてしまう現象があるらしい。

    これは面白い。

    Tブログ 「あああ」で変換してみろwwwwwwwww

    [via]
    面白ネタ収集

    OracleでNVARCHAR型のTimestampをFROM_TZ関数で使用する場合の注意点

    NVARCHARの文字列をタイムゾーンとしてFROM_TZに指定する場合は、CHAR型へのCASTが必要になります。
    これをしないと、「タイムゾーン リージョンが見つかりません」などのエラーになりタイムゾーンをいくら指定してもエラーになってしまいます。

    指定方法は以下を参照。

    SELECT
    FROM_TZ(
    '1999-12-01 11:00:00', CAST(どっかのテーブル.TIME_ZONE AS VARCHAR2(50 char)))
    FROM
    DUAL;

    Oracleで実行計画(Plan_Table)を確認する方法

    SQL文を作成するときに気をつけなければならないのは、Indexを貼っているにもかかわらずテーブルに対してフルスキャンしてしまう場合である。

    それを発見するためには、Oracleの実行計画を眺めてどこがダメかを判断する必要がある。

    まずはPlan_Tableを作成し、実行計画を見れるようにする。
    以下のSQL文を実行すれば作成される。

    create table plan_table (
    statement_id varchar2(30),
    timestamp date,
    remarks varchar2(80),
    operation varchar2(30),
    options varchar2(30),
    object_node varchar2(128),
    object_owner varchar2(30),
    object_name varchar2(30),
    object_instance numeric,
    object_type varchar2(30),
    optimizer varchar2(255),
    search_columns number,
    id numeric,
    parent_id numeric,
    position numeric,
    cost numeric,
    cardinality numeric,
    bytes numeric,
    other_tag varchar2(255),
    partition_start varchar2(255),
    partition_stop varchar2(255),
    partition_id numeric,
    other long
    );

    細かい設定は以下から参照。
    実行計画表示のための設定

    携帯からYouTubeにビデオをアップする方法


    Going My Wayさんより。
    もう完全にモバイルからなんでも出来ちゃう時代なんですね。
    基本なWebサービスはユビキタスが可能になってるから、いつでもどこでもブログの記事もアップできるし動画だってアップできちゃう。

    楽しい時代がやってきました。

    wtp-all-in-one-sdkにUnicode変換プロパティエディタを追加する方法

    wtp-all-in-one-sdkでプロパティファイルを開こうとしたときに、一応「プロパティ・ファイル・エディター」というエディターが入ってはいたんですが、どうやらUnicodeにエンコードしてくれない感じ。

    なので、いつも使っているプロパティエディタプラグインを追加インストールしました。
    方法はいたって簡単。以下の通り実行してください。

    • jp.gr.java_conf.ussiy.app.propedit_4.8.2_for_eclipse3.0を解凍します。
    • eclipse インストールディレクトリに上書きします。
    • eclipse を再起動します。

    プラグインのダウロードは以下からどうぞ。
    http://sourceforge.jp/projects/propedit/

    【関連リンク】
    native2asciiによるユニコード変換の煩わしさから解放されます。

    最近の仕事はeclipse3.3をイジイジすること

    最近要件定義ばっかりであんまり技術っぽいことをしていませんでしたが、eclipse3.3のリリースと同時にちょいプロを作成して遊んでいます。じゃない、仕事しています。笑

    all in one wtpみたいなのを使っているんだけど、これ楽しい。
    eclipse自体は相変わらず重いけど、個人的にはVisual Studio2005より好きになったかも。
    いや、また.NETを始めたらそっちがいいとか言いそうですが…

    結局エディターとかIDEって使い倒してナンボのモンと思っているから、ひたすらイジイジして機能の把握に精を出す毎日。プラグインでも作れたらかっこいいな~と感じてしまいます。

    ちなみにこの業界に入ったときから使い込んでいるエディターはPeggyちゃん。
    sakuraも使っていたけど、やっぱりシェアなエディターはいいです。もっと言うとPeggyを使い込んだらもう後戻りはできない。文章書くにもコード書くにもPeggy一本。
    やっぱりエディターを愛することができるのもエンジニアの重要な要素だと思っています。

    【関連リンク】
    Peggyの紹介

    Ruby On Railsのチュートリアル映像がたくさん置いてあるサイト

    Ruby On Railsのチュートリアル映像がたくさん置いてあるサイト
    うひょ~とワクワクしてしまうほどのRuby On Railsチュートリアルが置いてあるサイトのご紹介です。
    もちろん英語ですが、見てるだけで楽しくなっちゃう。

    まだまだ日本ではRuby On Railsを使ったWeb開発は盛んではない感じですが、これからに期待。
    サクッと作れちゃうのがいい感じですね。
    工数も少なくてすみそう。

    以下からどうぞ。
    Railscasts - Free Ruby on Rails Screencasts

    [via]
    100SHIKI.COM

    Ajaxでのクロスサイトスクリプティングで気をつけたいこと

    ここが危ない!Web2.0のセキュリティで書かれていた内容が面白かったのでメモしておきます。

    XSS(クロスサイトスクリプティング)は一般に広く知れ渡っているセキュリティホールですが、Ajaxを使った場合はさらにサニタイジングを意識しなければなりません。
    例えば一般的にAjaxで通信する場合、~~.doや~~.cgiなどの動的プログラムを呼び出しますが、単純に~~.txt、~~.csvといったファイルを指定することも可能です。
    この場合ファイルの中身は普通なテキストを想定していますが、HTMLタグやスクリプトが記述されていた場合にクライアント側で実行をしてしまうということです。

    ということを回避するには、

    • ファイルに対してアクセスさせない
    • JavaScript側でdocument.writeをする前にサニタイジングを行う

    といったことをしなければなりません。
    JavaScript側でのサニタイジングを行うのは、ちょっと面倒なので、単純にファイルにアクセスさせないほうで実装したいもんです。
    基本的にはクライアントにHTMLを返す直前でサニタイジングしたいですね。

    Eclipseの初期起動時のヒープの大きさを指定する方法

    あまり指定することはないと思うが、メモリをそこまで積んでいないPCなら指定するほうが良いかも。
    以下にEclipseのメモリ指定方法を記載する。

    eclipse.exeのショートカットを作成し、プロパティのリンク先に-Xms40m -Xmx512mのように指定する。

    以下のような感じです。

    C:\~~\eclipse.exe -Xms40m -Xmx512m

    -Xms 初期ヒープサイズの指定。空きメモリの80%くらいが望ましい。 -Xmx 最大ヒープサイズの指定。初期ヒープサイズと同じが望ましい。

    コンピュータ派かコンピューター派か

    “コンピューター”と“コンピュータ”正しいのはどっち?というエントリがあったので、ボクもちょっと考えてみる。

    実際設計書とかに記述する場合は、ボクはたいてい「コンピュータ」にしているっぽい。
    なんでかはあんまり考えたことがないが、こうしている。

    JISによるとコンピュータが正しいようだが、規定しているわけではないので、コンピューターでもいいようである。

    JISでは、3音以上の単語の長音符号は取っています。

    とのことなので、実際には「ターミネーター」ではなく「ターミネータ」?かな?
    なんか変だな。

    う~ん、やっぱり英語スペルで「ter」は伸ばしたほうがしっくりくるような気がする。
    まぁどっちでも良いですがね。笑

    FirefoxとIEのCSSの違いをリアルタイムで表示してくれる「CSSVista」

    FirefoxとIEのCSSの違いをリアルタイムで表示してくれる「CSSVista」
    マルチブラウザ対応の開発だと、いちいちFirefoxとIEを開いてF5の連発になってしまいますが、これを使えばリアルタイムですぐに違いが把握できちゃう。

    こうゆうの今までになかったからすごく助かる。

    以下が動作条件です。

    環境:Windows XP
    Framework:Microsoft .NET Framework Version 2.0

    ダウンロードは以下からどうぞ。
    CSSvista

    【関連リンク】
    CSSvista IE・Firefoxで同時に表示確認・CSS編集ができるフリーソフト

    Eclipse3.3(Europa)を一まとめにしたwtp-all-in-one-sdkを使ってみた

    Eclipse3.3(Europa)を一まとめにしたwtp-all-in-one-sdkを使ってみた
    気が付けばeclipseも3.3がリリースされているようなので、さっそく使ってみました。
    しかもついついプラグインを個別に入れるのが面倒なので、wtp-all-in-one-sdkダウンロードしちゃった。
    このwtp-all-in-one-sdkはeclipse3.3に合わせてリリースされているので中身は3.3。

    全体的にアイコン達がちょっと丸みをおびたような気がする。
    あと個人的に良いと思ったのが、アンドゥとして間違って消しちゃったファイルも復元できるとか。
    今までって間違えてファイル消しちゃったら、ローカルファイルヒストリーからファイル持ってきてとかやってたけどこれからはそんな必要もない。

    エディタに関しては、DOMのインテリセンスが使えるので、
    「window.」と入力すれば、「alert」って出てくる。
    これはすごい大きい。
    特に画面周りを頻繁に触る人にはもってこいでしょう。

    これからのJava開発には必須なIDEになることでしょう。

    wtp-all-in-one-sdkに同封されているプラグインは以下の通り。

    • HTMLエディタ
    • JavaScriptエディタ
    • CSSエディタ
    • XML用の各エディタ
    • サーバ連携モジュール
    • データベース連携モジュール

    これだけ入っていれば十分、逆にこれ以外はあんまりいらない。

    all-in-oneのwtpを使いたいかたは以下から。
    Web開発者必須の全部入りEclipse「wtp-all-in-one 2.0」もリリース

    使い方やレビューを見たいかたは以下から。
    ついに登場! Eclipse 3.3 - 新機能と同梱プラグインを速攻レビュー

    EclipseでTwitterするプラグイン「Twitterclipse」

    普段からTwitter依存しているボクには溜まらないプラグインだ。
    EclipseでTwitterするプラグイン「Twitterclipse」
    ぶっちゃけコード書いてるときくらいTwitterを忘れなさいっ。と思ってしまうが、
    それでもTwitterしたい人のためのプラグイン。

    生産性が落ちてもTwitterしたいっ!という人は使ってみてはいかがだろうか。
    でも仕事にならない可能性

    EclipseでTwitterするプラグイン「Twitterclipse」

    Web開発者必須の全部入りEclipse「wtp-all-in-one 2.0」

    なんともうれしい話だ。
    普段IDEはEclipseを多用するが、いっつもどのプラグインを入れようかいろいろ迷ってしまう。

    最近はいまだにTomcatプラグインでも開発だが、別にこれはこれでよい。

    でも今後あれやこれやを選ぶ労力を減らしたい人はWTP内臓のEclipse「wtp-all-in-one 2.0」を使ってみてはどうだろうか。

    同封されている内容は、

    HTML、JavaScript、CSS、XML用の各エディタやサーバ連携モジュール、データベース連携モジュールなどが含まれているプラグイン

    つっ、使える!

    詳細は以下で
    Web開発者必須の全部入りEclipse「wtp-all-in-one 2.0」もリリース

    Home > 技術

    Tag cloud
    カテゴリー
    月別アーカイブ
    Powered by
    Powered by
    Movable Type Commercial 4.261

    Page Top