Home > 技術

技術 Archive

はじめてのiPhoneアプリ - カメラアプリを作る際にハマったことのメモ

とにかく情報はStackOverFlowたよりです。
なので必然的に、ググるときのキーワードも英語になっていきます。

Webに比べるとあまりにもまだまだiPhoneアプリの解説や資料は少ないので、以下の記事がどなたかの助けになれば幸いです。

AppCodeというIDEを使ってみる

appcode.png

JetBrains AppCode: an Objective-C IDE That Makes a Difference

もう、これはすごかった。
さすが1万もするアプリだなーという感じです。

XCodeでもAppCodeと同じようなことができるんだとは思いますが、あまりにも直感的に使えるIDEなので、これがないと厳しいです。
地味ですがダブルコートを打つと自動的に@が補完されるのとか助かります。

あとはコードフォーマッター、どうもXCodeにはないらしいので、これはかなり重宝しました。
リファクタリングもすごくいいです。

gitとも連携できるので、ファイルのヒストリーも見れます。
あとはもう触ればとりこですよ。

ただ一点だけ、
imageView.contentMode =
こう打ったら、この右側で補完されるものはcontentModeで絞り込んで欲しい。
すごいいっぱい出てくるから、毎回ググッて貼り付けてます。

あとは、
2011-12-11 - 人工無脳が作りたい
こちらを読むとさらに使いたくなります。

gitにも対応していてdiffをしてくれるので比較も便利!


AppCodeのカラースキーマをMonokaiにする

以下がカラースキーマの置き場所。
ここにxmlファイルを配置して、PreferencesのColorから選べばOK!

~/Library/Preferences/appCode10/colors/

WebStormで使っていたMonokaiテーマだと、うまくObjective-Cのカラーリングがされなかったので、

hezi/monokai-appcode

こちらを使ってみた。すごく良い感じ。


XCodeのアシスタントエディターがうまく機能しない

アシスタントエディターを使うと、画面がセパレートされ、.hファイルと.mファイルを同時にみたり、
storyboardとそれに紐付くControllerファイルを見ることができますが、これがたま〜〜に機能しなくなるときがあります。

具体的にはstoryboardで選択したViewとそれに設定しているCustomClassのViewControllerが開かない現象です。

これは、何回かXCodeを再起動すれば紐付くようになりました。
とくにstoryboardに配置するViewControllerの量が増えてくるとこの現象が発生するような気がします。

何が原因かはまだ不明。


Objective-Cでシングルトン

Objective-C でシングルトンパターン | Sun Limited Mt.
こちらの記事を参考に書いてみました。

■gist
Objective-Cでシングルトン -- Gist

使い方は、

プロパティの場合はこんな感じですね。


UILabelにPaddingを入れたい

UILabel のテキストのmargin やらpadding やらを設定して表示位置を調整する - laiso - iPhoneアプリ開発グループ
に書かれている方法でバッチリでした。

■gist
UILabelにPadding入れる -- Gist


画像をリサイズしたい

写真アプリなら必ずやりたくなる処理。
必要な分はメソッド化しておきました。

■gist
Objective-Cで画像のリサイズ系 -- Gist

こう書いてみたものので、画像まわりでハマったので、メモしておきます。
UIImageViewのサイズは320だとしても、その中に収める画像UIImageのサイズは640にしないとretinaでぼやけます。
はじめ分からなくて両方に320を指定していたのですが、ぼやけてしまってハマりました。

UIImageViewのリサイズコードは以下の感じです。

そしてさらに、imageView.contentMode = UIViewContentModeScaleToFillにします。
これでInstagramなどと同じようにキレイな画像が出るようになりました。
おー!


UILabelにセットした文字列が長い場合にfontが自動で小さくなるのを防ぐ

XCodeのAutoshrinkのチェックを外す。
或いは、UILabelをプログラムからViewにaddする。


カメラ機能の実装

今回の主人公であるカメラ部分の実装になります。
はじめ、ダレもがやるUIImagePickerControllerを使った実装をしていたのですが、どうもInstagramやPathと違う、何かが違う...
となりまして、いろいろ調べてみると、AVCaptureDeviceクラスを使うとそれっぽいことが可能になると。
(なんだかややこしそう...)

ざっくりデザインを無視して、

  1. カメラが撮れる
  2. アルバムから選べる
  3. 前面カメラを選べる
  4. Flashを切り替えられる
  5. フォーカスできる
  6. 閉じるボタンがある

これらの機能をシンプルに1個のViewControllerで実装してみました。
カメラを撮ると画面右下にちっちゃく表示するようにしています。

あとは確認画面に行ってフィルター掛けてもいいし、ゴニョゴニョしてもいいし。

意外と日本語のサイトでも海外でもそうですが、シンプルにまとまって一つのプロジェクトになっているのがなかったので、
今後これをもとにいろいろ遊んでみようと思います。

■github
hisasann/AVCaptureDeviceCamera


絵文字をMySQLに入れる方法

MySQLで4バイトのUTF-8文字を扱ってみる - HHeLiBeXの日記 正道編

utf8mb4にするというお話


カメラのフラッシュのオートが効かない

はじめ以下のようにtouchModeAVCaptureTorchModeAutoを指定していたんですが、
暗いところで撮影してもいっこうにフラッシュがつかなくてハマっってしまいました。

実際にはflashModeAVCaptureFlashModeAutoを入れるとうまいこと行きました。

たしかにトーチじゃないよな。


iOSで使えるFilterの種類が知りたい!

出力結果:

properties - (
CIAdditionCompositing,
CIAffineTransform,
CICheckerboardGenerator,
CIColorBlendMode,
CIColorBurnBlendMode,
CIColorControls,
CIColorCube,
CIColorDodgeBlendMode,
CIColorInvert,
CIColorMatrix,
CIColorMonochrome,
CIConstantColorGenerator,
CICrop,
CIDarkenBlendMode,
CIDifferenceBlendMode,
CIExclusionBlendMode,
CIExposureAdjust,
CIFalseColor,
CIGammaAdjust,
CIGaussianGradient,
CIHardLightBlendMode,
CIHighlightShadowAdjust,
CIHueAdjust,
CIHueBlendMode,
CILightenBlendMode,
CILinearGradient,
CILuminosityBlendMode,
CIMaximumCompositing,
CIMinimumCompositing,
CIMultiplyBlendMode,
CIMultiplyCompositing,
CIOverlayBlendMode,
CIRadialGradient,
CISaturationBlendMode,
CIScreenBlendMode,
CISepiaTone,
CISoftLightBlendMode,
CISourceAtopCompositing,
CISourceInCompositing,
CISourceOutCompositing,
CISourceOverCompositing,
CIStraightenFilter,
CIStripesGenerator,
CITemperatureAndTint,
CIToneCurve,
CIVibrance,
CIVignette,
CIWhitePointAdjust
)

[via]
iphone - CIColorPosterize in iOS - Stack Overflow

フィルターはこれから実装するのですが、
『第3回 iphone_dev_jp 東京iPhone/Mac勉強会』で vImage について発表してきました - Over&Out その後
こちらを見て、vImage vs CoreImage vs OpenCV といろいろやり方があるのが分かりました。
この道もそれはそれは大変そうです。


UIImageViewにUITapGestureRecognizerをセットしてもイベントが発生しない

UIImageViewに設定したGestureイベントが発生しない - 日々精進
こちらの記事のとおりなんですが、

こんな感じでUIImageViewにUITapGestureRecognizerをセットしても、イベントが発生しない。
これはUIImageViewのuserInteractionEnabledをYESにすれば発生するようになります。


メモリ不足によりviewDidUnloadが呼ばれた場合に状態を復元する方法

Cocoaの日々: UIViewController - 状態保存復元パターン

今回、とってもハマったのが、このviewDidUnloadだ。

落ちないiPhoneアプリが作りたい自分のための、押さえておくべきポイントたくさん。 - かってぃのブログ | choilog [チョイログ]
【iPhone】メモリ不足時のシミュレートとデバッグ | iPhoneアプリで稼げるのか
2009-01-21 - f-shinの日記 - iPhoneアプリ開発グループ
iPhoneアプリ開発まっしぐら★ - iPhoneアプリ開発グループ
Safx: ViewControllerにおけるビュー管理サイクルとメモリ警告シミュレーションによるアンロード処理について
このあたりをよく読むと理解できるか、今回発生した現象はあまりググっても出て来なかったのでここにメモしておきます。

今回使ったPathライクなUIライブラリはECSlidingViewControllerですが、
これは最上位となるViewControllerがいて、それが実際のECSlidingViewControllerになります。

つまり、

  • ViewController
  • TopViewController

の2つがいて、ViewControllerはECSlidingViewControllerをインプリメントしているだけ、
本当のトップViewはTopViewControllerになります。

TopViewControllerにあるUITableViewをタップするとサムネイル画面に遷移する仕様なので、
ThumbnailViewControllerとしときましょう。

このThumbnailViewController画面でカメラをModalで開きます。
(下からニュルっと出てきます)

こんな感じのコードです。
よくあるコードですね。

このCameraViewControllerを開くまでに、画像を結構表示しているとして、viewDidUnloadが発生しやすい状態にしておきます。(またはシミュレータででメモリワーニングを出す)
そして、CameraViewControllerをModalで開いてTumbnailViewControllerのviewDidUnloadが発生し、CameraViewControllerを閉じたときに画面が真っ白になってしまう現象が発生しました。
ここが真っ白になってしまうは、ECSlidingViewControllerの影響かもしれません。

いろいろな解説記事を読むと、viewDidUnload後にビューが表示されるタイミングでもう一度viewDidLoadが発生すると書かれているんですが、これが発生しませんでした。

結論を言うと最も親であるViewControllerもviewDidUnloadされてしまっていました。

これにより、TumbnailViewController意外のTopViewControllerやViewControllerもなくなってしまっていたので、真っ白の画面になってしまいました。
そこでViewControllerのviewDidUnloadが発生したタイミングでTumbnailViewControllerまでを復元するようにするコードを書きました。

つまり、メモリワーニングでModal以外のViewが破棄されても、Modalが閉じられて後ろ側が見えるようになる瞬間で、

  • ViewControllerのviewDidLoadが呼び出される
  • TopViewControllerを復元
  • ThumbnailViewControllerを復元
  • サムネイル画面があたかもずうっとあったかのように見せる。

こうなりました。(ややこしい!)

ちなみに、ModalではなくNavigationでやった場合、同じようにメモリワーニングが起こると、TopViewControllerまで強制的に戻される動作をするので、あまりにも不自然な動作ゆえにやめました。

iPhoneアプリはメモリまわりがかなり難しいですが、viewDidUnloadもこれまた難しい。
以下に、真っ白にはならないのですが、メモリワーニング後に適切な画面が表示されないパターンを作ってみました。
参考までに。

■github
hisasann/ModalDidReceiveMemoryWarning


UIImagePickerControllerでフォトライブラリーを開いたときのナビゲーションバーの色を変えたい

navigationBar.tintColorにUIColorを入れると変えられるようです。


PullToRefreshしたい!

sonnyparlin/PullToRefresh
これを使えばほんとうに簡単に実現できました。

サンプルのプロジェクトを作成したのでこちらを参考にしてみてください。

■ArcPullToRefresh
hisasann/ArcPullToRefresh

だいたい以下のようなコードを追加するだけになります。


自分のアプリのメモリ使用量をアプリ内で知る方法

こんな感じ。

[via]
自分のアプリが使用しているメモリサイズを取得するには - The iPhone Development Playground


データを保存する場所について

ディレクトリいろいろ。

/アプリ名.app
メインバンドルと呼ばれている。アプリのリソースファイルを保存するためのディレクトリ。読み取り専用。

/Documents
アプリがファイルを作成して保存することができるディレクトリ。永続化したデータを格納する場合ここを使うのが一般的

/Library/Caches
アプリが一時的に使う情報を保存するディレクトリ

/Library/Preferences
アプリケーションの設定を保存するディレクトリ。NSUserDefaults のデータが保存される

/tmp
一時ファイルを保存するディレクトリ。アプリが動作してないときに消される可能性がある

[via]
iOS でデータを永続化する方法 - A Day In The Life

パスの取得いろいろ。

NSHomeDirectory()
/var/mobile/Applications/FBAD8D21-CFFC-4804-85AC-7F6F02DCB836

NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES)
/var/mobile/Applications/FBAD8D21-CFFC-4804-85AC-7F6F02DCB836/Documents

NSSearchPathForDirectoriesInDomains(NSLibraryDirectory, NSUserDomainMask, YES)
/var/mobile/Applications/FBAD8D21-CFFC-4804-85AC-7F6F02DCB836/Library

NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES)
/var/mobile/Applications/FBAD8D21-CFFC-4804-85AC-7F6F02DCB836/Library/Caches

NSTemporaryDirectory()
/private/var/mobile/Applications/FBAD8D21-CFFC-4804-85AC-7F6F02DCB836/tmp/

[via]
アプリのsandboxをURLを取り出す - iPhoneアプリケーション開発


Exif情報を付与する - これは苦労しました...

もうこれはとにかくハマりました。
Exifなどのメタデータを自由に操作するにはどうするか - AppStair
JPEGファイルのExif情報を読み書きする - 強火で進め
無題メモランダム: [iOS]画像にEXIFなどのメタデータを付加する方法メモ
[AssetsLibrary] フォトライブラリの写真にExif情報を付けて保存する - Ni chicha, ni limona - 平均から抜けられない僕 - iPhoneアプリ開発グループ
このあたりのすばらしい記事を読んでいろいろ試してみたんですが、どうしてもサーバーに画像をPostするとExifが入らない現象に悩まされました。

結果的に、PostするときにUIImageからNSDataに変換していたんですが、ここでExif情報を抜け落ちているのが分かりました。
こんなコードです。

これをやってしまうと、Exifが抜け落ちてしまう...
以下に2種類のExif付与の方法を書いておきます。

  1. 画像ファイルは作らずにNSDataを作る方法
  2. 画像ファイルを作る方法

たとえば、Exifを付与した画像ファイルを、また別のViewでも使いたい場合など、ファイルに保存しておくと良いかもしれません。

Exifを付与しNSDataを作成するサンプルコード

以下のコードでは、

  • kCGImagePropertyExifDateTimeOriginal
  • kCGImagePropertyExifDateTimeDigitized

の2つのExif情報を付与しています。

■gist
Exifを付与しNSDataを作成するサンプルコード -- Gist

Exifを付与し、/tmpに画像を保存するサンプルコード

以下のコードでは、


  • kCGImagePropertyExifDateTimeOriginal

  • kCGImagePropertyExifDateTimeDigitized

  • の2つのExif情報を付与しています。

    ■gist
    Exifを付与し、/tmpに画像を保存するサンプルコード -- Gist

    そして、これをサーバーにPostする際に

    のようにしてdataを作りこれをPostしています。
    ちなみにExifを抜き出す作業はそこそこメモリ資料率が上昇します。
    これはどうも画像サイズが大きければ大きいほど上昇するようです。なので、小さいサイズにしたUIImageから抜くとかすると抑えられる感じです。

    ■参考リンク
    Exif TAG

    フォトライブラリーから選んだ画像のExifから撮影日を取得したい

    これもたいそうハマったんですが、
    UIImagePickerControllerのsourceTypeにUIImagePickerControllerSourceTypePhotoLibraryを指定してフォトライブラリー画面を出し、そこから写真を選ぶと

    こんなメソッドが呼ばれます。

    このときにUIImagePickerControllerのallowsEditingをNOにしていると、Exif情報を持っているはずのeditingInfoがnilになってしまいます。

    YESにするとExifが入った状態になります。

    [via]
    [iOS][Objective-C]カメラを使ってみようの巻 | なんだかんだ言って甘いもの好きでしょ?日記

    UIImagePickerControllerでイメージピッカーからExif情報を抜き出す

    ALAssetsLibraryを使う以下の方法で落ち着きました。

    ■gist
    UIImagePickerControllerでイメージピッカーからExif情報を抜き出す -- Gist

    [via]
    UIImagePickerController経由でカメラロールの写真のExifにアクセスしたいねん | Eudyptes Chrysocome

    このメソッドの引数のimageのサイズは以下。(iPhone4の場合)

    image.size.width - 640.000000
    image.size.height - 640.000000

    editingInfoから抜き出したeditedImageのサイズは以下。

    editedImage.size.width - 0.000000
    editedImage.size.height - 0.000000

    editingInfoから抜き出したoriginalImageのサイズは以下。(つまりもとの画像サイズ)

    originalImage.size.width - 1434.000000
    originalImage.size.height - 1920.000000

    [via]
    iphone - UIImagePickerController allowsEditing=YES Issue - Stack Overflow

    位置情報へのアクセスを許可していない場合に、ALAssetsLibraryからフォトライブラリーにアクセスすると出るエラー

    どうもALAssetsLibraryを使ってExifを抜き出すコードがあると?、位置情報を取得しても大丈夫ですか的なダイアログで出るんですが、そこでいいえを選択するか、はいにはしたけどあとからシステム環境設定でいいえにした場合に、ALAssetsLibraryのfailureBlockに入ってしまうようです。

    2012-08-01 18:32:48.531 HogeAPP[15197:707] error - Error Domain=ALAssetsLibraryErrorDomain Code=-3311 "User denied access" UserInfo=0x2c81e0 {NSLocalizedFailureReason=The user has denied the application access to their media., NSUnderlyingError=0xceae140 "The operation couldn't be completed. (PersistentURLTranslator error 1.)", NSLocalizedDescription=User denied access}

    はじめ原因が分からなかったんですが、よくよく自分がやったことを思い出したら許可しないにしたなーと。

    iPhoneアプリ開発塾
    iPhoneアプリ開発塾
    posted with amazlet at 12.09.11
    カワサキ タカシ
    技術評論社
    売り上げランキング: 1998

    DataPickerを下からニュルっと!

    [iPhone] 下からニュッと出てくるDatePicker | BuGcloUd.com
    こちらの記事を参考に作りました。

    でも、DatePickerって出現すると10MBぐらいメモリ使用量があがるんですね。


    縦長のUIScrollViewをstoryboard上でデザインしたい!

    iPhone画面サイズを超えるViewをStoryBoardに配置する方法について - Google グループ
    こちらで議論されていますが、結果的にぼくも便乗して、
    StoryBoard&スクロールビューで画面サイズ調整 - Object for cutie
    この方法でやってみることにしました。

    つまり、

    「親となるViewControllerがあり、その中にContentSizeの高さが長いstoryboard上でデザインしたUIScrollViewを配置することができるようになる。」

    ということになります。

    たとえば、入力→確認という画面遷移を考えたときに、
    入力画面の項目が多ければ、460pxの中には収まりません。
    そうするとデザインが目で確認しながらではなく、プログラムから行う必要が出てきてしまうので、この方法で助けられました。

    ただし、親のUIViewControllerで、

    のようにする必要があるので、不必要なUIViewControllerのインスタンスが生成されているかもしれません。
    とはいえ、メモリを監視しているとそこまで上がらないので大丈夫だと思われます。


    RGBをUIColorとして使いたい

    これは僕が知らないだけかもしれませんが、XCode上の色を選ぶことができるColorsビューにて、
    Web Safe Colorsのところで指定したい16進を入力しても、ないみたいに言われて指定できないので
    プログラムから行うことにしました。

    16進数から10進数のRGBに変換は以下のサイトがいいです。
    もうここに助けられた!
    RGB変換 (16進数→10進数) (16進数→10進数)

    こんな感じで使います。


    UITextViewをタップしたい!

    覚え書き☆iPhoneプログラミング UITextViewでタップイベント
    こちらのとおり、カスタムなUITextViewなクラスを作って、touchesBeganに処理を書くようにしました。

    これはUITextViewをタップしたときにDatePickerを表示するときに使いました。
    ちなみに、DatePickerって表示すると10MB近くメモリが上昇するんですが、結構重いんですね。


    UITextFieldをタップしたときにキーボードの下に隠れないようにする

    iPhone SDKで、コンテンツがキーボードで隠れないようにする。 - このブログは証明できない。
    TextFieldにテキストを入力したとき画面の下が隠れてしまわないようにする方法 - ガジェット充まゆたまのiPhone開発知恵袋
    こちらの記事を参考にさせていただきました。

    そして最終的なコードが以下。

    とその前に、現在アクティブなUITextFieldを取得するために
    iPhone SDKで、アクティブな(フォーカスのある)UITextFieldを取得するには? - このブログは証明できない。
    こちらのコードも参考にさせていただいた。

    サンプルコード

    ■gist
    UITextFieldをタップしたときにキーボードの下に隠れないようにする -- Gist

    ちなみにですが、UITextViewの場合は、かってにフォーカス?するので、あえてここでUITextViewの表示位置にスクロールするということはしていないです。
    あと、いろいろ検索して見つけたコードを試してみたところ、上記のパターンじゃない方法(忘れちゃいました)で書かれたコードを使うと、UITextFieldをタップしてもアクティブにならない現象が発生しました。
    何度かタップするとアクティブになるんですが、その挙動がいやで、上記のパターンでは起こらなかったのでこちらを採用しております。


    UINavigationControllerを指定したView、または一番初めのViewに戻したい

    UINavigationControllerを2ページ目に戻す方法

    UINavigationControllerを最初のページに戻す方法

    [via]
    UINavigationControllerを使って、指定したビューまで戻ってメソッドも実行する|成長の果実

    もどると、ちゃんとdeallocも呼ばれます。


    複数開いたモーダルビューを一気に閉じたい!

    モーダルビューをすべて閉じる方法を教えてください « 寺子屋サルでき旧館 | iPhoneアプリ開発をもっともっと楽しく!困ったらみんなで解決!
    presentModalViewControllerで表示した2階層以上の画面から一気に戻る方法 - Faith and Brave - C++で遊ぼう

    これなかなか難しいですね。
    そもそもiOS5からなのか、viewWillAppear時に[self dismissModalViewControllerAnimated:YES];を呼んでも消えてくれなくて、
    viewDidAppearなら消えてくれます。

    なので、一気に消えるというよりは、パラパラと消えていくという感じになってしまいました。
    そこでぼくは、

    1. 親となる画面から1つ目の子画面を開く
    2. 1つ目の子画面から2つ目の子画面を開くんだが、その命令は親画面に移譲する
    3. 親画面が1つ目の画面を消して2つ目の子画面を開く
    4. 2つ目の子画面から1つ目の子画面に戻るときも同じように親画面に移譲する
    5. 2つ目の画面を閉じると1枚しか開いていないので、あたかも2枚閉じたように見える

    この挙動は、カメラを撮る→確認画面に行く→(ナビゲーション)→投稿画面に行くというInstagramの挙動と同じ感じかなーと思っています。

    親画面のサンプルコード

    1つ目の子画面のサンプルコード

    2つ目の子画面のサンプルコード

    こんな感じです。
    ここに行き着くまでに結構ハマりましたね。

    ※この方法は最終的に使いませんでした。
    とくにモーダルを開くシーンで使うのですが、メモリワーニングなイベントが起きた場合に親のViewControllerが破棄されると、2つ目の画面への遷移が親からなので、遷移できなくなるためです。
    なので、一気に2枚のViewを閉じる画面はなくしました。


    Could not find a storyboard named 'iPhone' in bundle NSBundleが出る場合

    なんでか不明ですが、storyboardがうまくロードされない場合がある。
    それは、誰かにプロジェクトを渡して、その人のXCodeでビルドしたときに起こりました。

    2012-08-03 13:29:13.804 HogeAPP[1403:1a303] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'Could not find a storyboard named 'iPhone' in bundle NSBundle (loaded)'
    *** First throw call stack:
    (0x1d09022 0x1979cd6 0xf069f2 0xadbd60 0xadbff8 0xadb17f 0xaea183 0xaeac38 0xade634 0x26c3ef5 0x1cdd195 0x1c41ff2 0x1c408da 0x1c3fd84 0x1c3fc9b 0xadac65 0xadc626 0x24cd 0x2435)
    terminate called throwing an exception

    解決策は以下の通りで、いったんstoryboardの参照を削除して、Finderからもう一度XCode上にドラッグしてあげる。
    これでビルド時に上記エラーがでなくなりました。

    1. Right-click on your MainStoryboard.storyboard in the Project Navigator.

    2. Select Delete and click Remove References Only.

    3. Right click on InfoPlist.strings and select "Show In Finder". (This is just my lazy way to open the folder containing the storyboard in finder.)

    4. Drag the MainStoryboard.storyboard from Finder back into the project.

    via: ios - XCode 4.2 MainStoryBoard Not Found - Stack Overflow

    [via]
    ios - XCode 4.2 MainStoryBoard Not Found - Stack Overflow


    メモリリーク箇所を発見する、そして循環参照をなくす!

    これはそれはそれは大変な作業です。

    静的アナライザ

    メニューバーの「Product→Analyze」よりXCodeに発見してもらう。
    ただし、以下のようにあくまでも補助として使うほうがよさそうです。

    Clang Static Analyzer を使うとメモリリーク箇所を解析して教えてくれます。完璧じゃないので油断は禁物ですけど。ちなみに Xcode3.2 からは標準で Clang Static Analyzer が組み込まれています。Build > Build and Analyze で解析できます。


    via: iPhoneアプリ開発時のメモリ管理で気をつけること - A Day In The Life

    ■参考リンク
    iPhoneアプリ開発時のメモリ管理で気をつけること - A Day In The Life

    Instruments

    InstrumentsUserGuide.pdfを読みながらがんばっているが、やはりInstrumentsの使い方はなかなか難しい。

    特にActivitiMonitorのReal Memがどれぐらいリアルなのかが気になるw
    聞いた情報だと、開放されたメモリもここに表示されている?とかで、結構なメモリ量になっている。

    Instruments.png

    だいたいアプリ起動時は8MBほどで、いろいろなViewやコントロールを開くとどんどん上がっていく。
    このどんどん上がっていくViewControllerにdeallocのメソッドを書いて、本当に開放されているかをチェックしてみたら、これまた開放されていない箇所が盛りだくさんだった。

    また、ActivitiMonitorではなくAllocationsでメモリ状態を監視した場合の各列の意味は、
    Instruments の Leaks の見方(Live Bytes や Living の意味) - Over&Out その後
    こちらに詳しく書かれていました。

    Live Bytes



    The Live Bytes column indicates how many of this type of object have been allocated and still are around in memory.


    該当するタイプのオブジェクトの現在のメモリ使用量

    via: Instruments の Leaks の見方(Live Bytes や Living の意味) - Over&Out その後

    こちらが実メモリということなんですかね。
    でもActivitiMonitorでは起動時8MBぐらいだったのが、こちらでは1MBほどになっている。
    ここはまた別で調査しないと。

    循環参照なサンプルコード

    たとえば、UIViewController内で何かLogicを呼び出し、このコールバックとしてさらに何かを実行した場合、
    自分自身を表すselfをブロック内に渡したくなる。

    ただし、これだと

    • UIViewControllerがLogicの参照
    • Logicがselfを通じてUIViewControllerを参照

    という循環参照が発生してしまう。
    最悪、deallocが呼ばれずにメモリ開放されなくなってしまう。

    循環参照しないサンプルコード

    まるでJavaScriptのようなコードだが、これで循環参照を防ぐことができます。

    __weakで弱い参照状態にして、あくまでも参照カウンターは上げないのがポイントです。

    ブロック内にselfを渡したり、インスタンス変数を渡したりするとメモリが開放されないということを知るまでに結構な時間を費やしました。
    この作業を地道に行なっていったところ、目的のほぼすべてのViewControllerでdeallocが呼ばれ、Real Memも増えるけど下がるという状態にまでもって行けました。

    余談ですが、facebookもinstagramも50MBを超える量のメモリをガンガン使っているので、最終的にメモリが開放された時点で50MB以下になっていればいいのかなーなんて思いました。

    ■参考リンク
    メモリリークを調べたい - ちくわプログラマにっき
    Instruments の Leaks の見方(Live Bytes や Living の意味) - Over&Out その後
    deallocが呼ばれない - てきとーブログ


    InstagramやTweetbotのようなカスタムなタブにしたい!

    【iPhone】任意のデザインにタブバーをカスタマイズする - 坊やがゆく
    こちらの記事の、
    PoohKid/FreeDesignedTabBar2 · GitHub
    この方法がすばらしいです。

    このカスタムタブの方法も地味〜にあんまりネットになかったりするので、助かりました。
    すべてのタブを画像にするなど、本当に独自にやりたい場合にこれで行けます。


    同時タップによる多重遷移のエラーに対処する

    指2本で複数のオブジェクトを一緒にタップする場合になります。

    Modalを複数開いてしまうケースのエラー

    *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'Application tried to present modally an active

    UITableViewで複数のCellをタップした場合のエラー

    Unbalanced calls to begin/end appearance transitions

    回避サンプルコード

    かなり力技ではあるが、以下のようにフラグを設けて、すでにオープンしている場合はそれ以降の呼び出しを無効にする。

    今回はUITapGestureRecognizerを使って、画像たちにModalを開くイベントをセットしていたので、このような同時タップで
    イベント自体が2回走ってしまい、2回目のModalOpenでエラーになってしまう。

    こうゆうことにも配慮が必要なのだとすごく勉強になったエラーでした。


    ライブラリを追加したときにエラーになる場合

    以下のようなエラーが出る場合がある。
    これはライブラリをプロジェクトに追加したんだが、XCodeの「Target Membership」に追加していないときに発生する。

    Undefined symbols for architecture armv7:
    "_OBJC_CLASS_$_Stats", referenced from:
    objc-class-ref in AppDelegate.o
    ld: symbol(s) not found for architecture armv7
    clang: error: linker command failed with exit code 1 (use -v to see invocation)

    ライブラリの.mファイルを選択し、XCode上から追加してあげよう。
    ライブラリでなくても普通にViewControllerのクラスを追加したときに、別のターゲットにチェックを付けていないと同じ現象は発生する。


    リジェクトされたくないので一読

    iPhoneアプリ審査での111の禁止項目(意訳) | fladdict


    各種アイコンのサイズ

    [iOS] アプリに必要なアイコン・起動画面の画像サイズ&ファイル名 | tande lab.

    使ったライブラリ

    R9HTTPRequest

    HTTP通信を簡単にしてくれたライブラリで、国産ということもあり、すごく馴染みやすかったです。
    非同期でブロックをコールバックに渡すスタイルなので、JavaScriptっぽくて使ってみました。

    iPhoneアプリ開発がはじめてだったので、このライブラリにはほんと助けられました。

    一点、画像をPostする際にメモリリークしている箇所があったので、nilを入れるように修正しました。

    pull requestした。
    Pull Request #1: 画像Post時のメモリリーク解消 by hisasann · glassonion1/R9HTTPRequest

    ■ダウンロード
    glassonion1/R9HTTPRequest

    ■解説
    シンプルで簡単に HTTP 通信が出来るライブラリを公開しました - A Day In The Life

    この後、結局のところ通信のタイムアウトがR9HTTPRequestだと240秒以下にできない問題があったので、ASIHTTPRequestに乗り換えました。
    どうもこれがデファクト?っぽい感じだったので。
    あかばね式 [iPhone]POSTする場合のタイムアウト設定値が無視される(場合がある)件

    R9HTTPRequestとほぼ同じようなコードなので、乗り換えはかなり簡単でした。
    ただしASIHTTPRequestはARCに対応していないので、
    ARCを有効にしたプロジェクトでASIHTTPRequestを使用する|成長の果実
    こちらで紹介されている、「-fno-objc-arc」を記述する必要があります。

    もう開発が止まっているライブラリですが、これはなかなかよいです。

    ■リンク
    ASIHTTPRequest Documentation - All-Seeing Interactive

    ECSlidingViewController

    PathなUIを実現する必要があって、でも自分で一からは厳しいなと思っていて、
    Facebookアプリを真似たメニュー機能を実現「ECSlidingViewController」 - MOONGIFT|オープンソース・ソフトウェア紹介を軸としたITエンジニア、Webデザイナー向けブログ
    こちらの記事を読んで採用してみました。

    実際には、導入もすごく楽で、スムーズだし、これもまたすばらしいライブラリでした。
    おそらくPathライクなUI用のライブラリとしては、だんとつ人気なんじゃないでしょうか

    ■ダウンロード
    edgecase/ECSlidingViewController

    MBProgressHUD

    比較的よく使われているLoadingレイヤーを出すライブラリです。
    なかなか海外でも評価が高いので、採用してみたのですが、少し使い方に注意が必要でした。

    Demoのコードを見てみると、以下の様にバンバンaddSubviewしているんですが、

    これはviewを渡しているかなのかわかりませんが、dealloc後にも開放されずに残ってしまうようでした。
    そして、Demoをよく見てみたら、こんなコードをimplementしていて、ここでremoveしていました。

    ただこのコードはLoadingの表示が終わったら呼ばれるようなので、それだとLoadingを出すたびにインスタンスが作られるので、

    ぼくは、viewWillAppearで追加して、viewWillDisappearでremoveするようにしました。
    これでメモリは開放されます。

    これでLoadingを出すときにメッセージも渡しつつshowする感じになります。

    ■ダウンロード
    jdg/MBProgressHUD

    SBJson

    Objective-Cではこれ!というぐらい調べていくとこのライブラリになりました。
    JSON用のライブラリです。

    とくに問題なく使えました。

    ■ダウンロード
    SBJson

    Underscore

    まさかのUnderscore.jsのUnderscore.m版がありました。
    でもwhithoutしか使いませんでしたw

    ■ダウンロード
    Underscore.m

    [via]
    iPhoneアプリ開発で使えるObjective-Cライブラリの紹介 | SmartAppsCreative

    このUnderscoreの面白いところは、[obj hoge]のように本来ならブラケットで囲われるのが普通だが、丸括弧で呼び出す方法を提供している。
    それの解説ではないが、小さくまとめたものをgithubのほうに上げておきました。

    ■github
    hisasann/Objective-CnoSquareBracketMethodCall


    スマホアプリのデザインをいっぱい見たい!

    Recent / iOS UI Patterns (beta)
    もうここのサイトが本当に参考になります。
    比較的有名なアプリの画面が、画面のジャンルごとにわかれているのでとっても見やすい。


    読み物

    iPhoneアプリで食べていく――「ぐんまのやぼう」ができるまで (1/3) - ITmedia ニュース


    まとめ

    今回、あまりまわりに聞ける人がいない環境で、頼れるのはグーグルさんだけだったのですが、けっこうたいへんでした。
    とくにググっても有力な情報が出てこないばかりか、XCodeが古い時代の記事はそもそも間違っていたりと玉石混交過ぎました。

    なので、とにかく実験、実験を重ねて、なんとかつかむことができましたが。

    ほんと、こうゆうハマる作業が好きなのはプログラマーゆえですよね。

    ハマってなんぼ!

    どうもありがとうございました!


    今回読んだ本

    よくわかるiPhoneアプリ開発の教科書【iOS 5&Xcode 4.2対応版】
    森巧尚
    マイナビ
    売り上げランキング: 1615

    この本はほんと初歩の初歩ですが、それすらも分からなかったので、まずはこれをざっくりやってstoryboardの感触を掴みました。

    詳解 Objective-C 2.0 第3版
    荻原 剛志
    ソフトバンククリエイティブ
    売り上げランキング: 2386

    この本はすごい!
    けど、なかなかなハードルであります。気長に読んでいこうかと。

    AppCodeのキーバインドをVimにする方法

    ここ最近AppCodeでiPhoneアプリを作っているんですが、どうやらVimのキーバインドが使えるというのを今更知ったのでメモ。
    とくにわかりにくいのが、デフォルトではVimのキーバインドはインストールされていません。
    (Emacsは入っているのに!)

    なので、Vimのプラグインをインストールしてそれを設定するだけです。

    NOTE for Vim addicts
    If you want the powers of both worlds, Vim editing capabilities and AppCode's code knowledge and others -- install the ideaVim plugin and enjoy!


    via: AppCode Basics - Objective-C IDE - Confluence

    Vimプラグインをインストールする

    AppCodeのPreferencesからPluginを選択します。

    Settings.jpg

    プラグインペインの下のほうにある「Browse repositories...」をクリック。
    開いた画面でvimを検索します。

    Browse Repositories.png

    絞りこまれたら、「ideaVIM」をダブルクリックします。

    AppCode.png

    インストールが完了すると、AppCodeの再起動を要求されるので、再起動します。
    baseとなるキーバインド(ここではdefaltを選択しました)を選んでVimのキーバインドを作成します。

    Vimのキーマップを適用する

    AppCodeのPreferencesからKeymapを選択します。

    Settings-1.png

    ここでKeymapsからVimを選べばOK、というか再起動後は自動的にVimになっているのかな?

    まとめ

    個人的に結構痛いのが「di"」や「vi"」などのダブルコートの中を削除する系が使えないこと。
    あとは自分の.vimrcで設定したキーバインドが有効にはならないので、それをどの程度AppCodeのキーバインドに登録するかですね。

    それでもほとんどVimなので、使い慣れた(僕はまだ初心者ですが)キーバインドでコードを書けるのはうれしいのではないでしょうか。

    ■関連記事
    Vimをちゃんと使い始めてみる
    AppCodeで行末尾のキャレット配置を無効にする方法

    詳解 Objective-C 2.0 第3版
    荻原 剛志
    ソフトバンククリエイティブ
    売り上げランキング: 2408

    AppCodeで行末尾のキャレット配置を無効にする方法


    ここ最近、JetBrainsのAppCodeを使って、Objective-Cを書いているんですが、デフォルトの設定だと、マウスでクリックしたところにカーソルが移動してしまう現象になっていてすごく困ったので、この機能を無効にするメモ。

    たとえば以下のようなコードがあった場合に、

    NSLog(@"%@", nsarray);

    のコードの最後のセミコロンの後ろにはスペースがいないにもかかわらず、どこでもクリックでカーソルを持っていけちゃうところ。
    セミコロンの後ろをクリックしたなら、セミコロンの後ろにマウスカーソルが移動して欲しい!

    この機能を無効にする方法

    AppCodeの「Preferences→Editor」を選択し、右側のペインで、

    Allow placement of caret after end of line

    これのチェックを外す。

    Settings.png

    これで、比較的普通なカーソル操作が可能になる。
    また、マウスだけでなくキーボードでも同様の現象になるので、これデフォルトチェックじゃないほうがいいんじゃないかなーと思いました。

    JetBrains AppCode: an Objective-C IDE That Makes a Difference

    よくわかるiPhoneアプリ開発の教科書【iOS 5&Xcode 4.2対応版】
    森巧尚
    マイナビ
    売り上げランキング: 720

    XCode4.3.2にしたときにハマったことメモ - LLDBからGDBへ

    かなりハマった。
    もうTitaniumMobile触っているときバリにハマった。

    そもそもXCode4.2で開発をしていたんですが、やっぱり4.3にしないとね!ってことで4.3にあげてTitaniumMobileも動作するように設定したんですが、肝心のXCode上でのデバッグをしようとするとXCodeが固まる現象に悩まされた。
    Titanium Mobile2.0.xでXCode4.3を使う方法

    スペック

    MacOS X
    10.7.4
    XCode
    4.3.2
    iOS SDK
    5.1

    現象

    XCodeで新規プロジェクトを作成し、とくになんのコードも書かないでRunボタンを押すと、iPhoneシミュレーターが立ち上がるがちょっとすると応答なしになる。
    よって、「Option+Cmd+Esc」から強制終了する。

    ひたすらこの現象の原因を突き止めるべく、強制終了の嵐。
    よく分からなくしていたのが、過去の4.2時代に作ったプロジェクトは普通にRunを押すとiPhoneシミュレーターが起動してくれること。

    そこでとりあえず応答なしにはなるけど、しばらくほったらかしにしてみた。
    すると、応答なし状態から抜け出し、「Attaching xxxx.app」のようなメッセージが出てきた。
    ただし、これいじょういくらまってもうんともすんとも言わない。

    やったこと

    古いXCodeのアンインストール

    やれることはやっていくしかないので、古いXCode4.2をアンインストール

    $ sudo /Developer/Library/uninstall-devtools --mode=all

    これにより「/Developer」ディレクトリの中はすんごくキレイに!

    ちなみに、FileMerge.appのような便利ツールは

    /Applications/Xcode.app/Contents/Applications

    に入っている。
    4.2時代までは/Developerに格納されていたが、4.3からはXcode.appの中に取り込まれた。

    [via]
    iOS Simulatorの導入とiPhoneシミュレータ

    XCode4.3.1にしてみたり、4.3.2を入れなおしてみたり

    これは何の効力もなかった。
    むしろ以下のように4.3.1ではバグがあるので、やっぱり4.3.2を使いたい。
    (それでもまだバグがあるようだが...)

    うたブログ~情報編: Xcode4.3.1のバグ
    うたブログ~情報編: Xcode4.3.2のバグ修正のチェック結果

    途方に暮れる

    ・・・

    いろいろやった

    以下に書かれていること全部やった。

    • プロジェクトを Clean する

    • Xcode を終了させる

    • シミュレータからアプリを削除する



    など。実機で動かしていた場合は iPhone の電源を切るというのも手だそうです。

    解決しませんでした。。



    で、最終的に行ったのが「Mac を再起動する」


    via: iPhone シミュレータ実行後、main.m で落ちる | NEO-SHOCKER.COM

    さらにMacのアップデートもやっといた。
    その昔、TiでハマったときにiTunesをアップデートすると直る現象があったため。

    どうやらLLDBというデバッガーが有効になっていたためのようだ

    XCodeがiPhoneシミュレーターにアタッチができていないことを思い出してググっていたら、以下がヒット。
    EZ-NET: iOS シミュレーターが Attaching のまま進まない - Xcode4

    でも、ちゃんとAutomaticallyになっていたので解決策ではなかった。

    そして
    デバッガの変更 - hachinobuのメモ
    こちらを読んでいて、

    xcode4.3はデバッガが今までのGDBじゃなくLLDBがデフォルトで選択されている。


    via: デバッガの変更 - hachinobuのメモ

    これやっ!
    ということでSchemeを見に行ってみたら、

    やっぱり

    LLDB

    になってた!
    そして4.2時代に作ったプロジェクトは、GDBになってた!

    なので、これをGDBにしたらすぐにiPhoneシミュレーターが起動。やっとですよ。

    まとめ

    この2種類のデバッガの違いは、まるで分からないのですが、
    LLDBを使っている人が文字化けに悩んでいたりするようなので、とりあえずGDBで行くことにします。

    というか、こっちじゃないとiPhoneシミュレーターが起動しないので。

    追伸:
    みなさん、どうしてるんだろう...

    追記:2012-05-23

    LLDBでもiPhoneシミュレーターがちゃんと起動するときがある!
    がちょ〜〜〜ん!

    よくわかるiPhoneアプリ開発の教科書【iOS 5&Xcode 4.2対応版】
    森巧尚
    マイナビ
    売り上げランキング: 1089

    Titanium Mobile2.0.xでXCode4.3を使う方法

    4.2のときにTitaniumMobileをインストールし、いろいろ遊んでいたんですが、
    XCodeが4.3になってディレクトリ構造が変わったり、コマンドライン系のツールは別でダウンロードするようになったりといろいろと違いが出てきたのでここにメモ。

    スペック

    事前にLionちゃんを10.7.4にしておきます。
    (もしかしたら10.7.3の方は上げなくても大丈夫かも)

    MacOS X
    10.7.4
    Titanium SDK
    2.0.1.GA2
    Titanium Studio
    2.0.1

    手順

    1. Downloadsより「Xcode 4.3.2 for Lionをダウンロードします。
    2. XCode4.3.2をインストールします。といっても4.3からは.appファイル単品しかないので、アプリケーションフォルダに入れましょう。
    3. XCodeを開いて「Xcode -> Preferences -> Downloads」よりcommand line toolsをインストールします。
    4. ターミナルから
      sudo xcode-select -switch /Applications/Xcode.app/Contents/Developer
      を実行します。 これによりTitaniumMobileが見に行くiOS SDKの場所を切り替えることができます。
    5. https://github.com/downloads/pegli/ios-sim/ios-sim-xcode4.3.tar.gzをダウンロードし、解凍しときます。
    6. ios-simファイルを下記ディレクトリに配置します。 一応、ぼくはすでにあるios-simファイルをリネームとかしておきました。
      cp /path/to/ios-sim ~/Library/Application\ Support/Titanium/mobilesdk/osx/2.0.1.GA2/iphone/
    7. あとはすでに存在しているプロジェクトの場合は、cleanして、Run ConfigurationsよりiOS5.1を選んでビルドすれば完成です。 新規にプロジェクトを作った場合は、自動的にiOS5.1になります。

    ■関連リンク
    Titanium 1.8.xをXcode 4.3環境で使用するには? - Titanium News
    Titanium MobileでiOS 5.1(もしくはXcode 4.3)を扱う : Shibuya Blog
    Titanium and Xcode 4.3: Revisited « Appcelerator Developer Center

    ■関連記事
    MacOSX LionにTitanium Mobile(Studioも)をインストールしたときのメモ(2012-02-06時点)
    TitaniumMobileのハマりポイントとお作法メモ
    MacOSX LionにPhoneGapをインストールしたときのメモ(2012-02-09時点) - iPhone/Android対応

    Titanium Mobileで開発するiPhone/Androidアプリ (Smart Mobile Developer)
    北尾 雅人
    翔泳社
    売り上げランキング: 105027

    TitaniumMobileのハマりポイントとお作法メモ

    ここ最近TitaniumMobileの主に検証を行なっております。

    そして先日Titanium meetup Tokyo #17 (五反田) : ATNDにおじゃまして@masuidriveをはじめとする多くのTitaniumMobileファンの方々とお話ができました。
    すごく楽しかったです!

    僕がTitaniumMobileに触り始めて約一ヶ月ほどたちますが、ハマったポイントをつらつらメモしてみました。
    使い方やTitaniumMobile自体のバグなど、まだ難しい部分は多々ありますが、4月に2.0がリリースされるようなので、今後が本当に期待できるフレームワークです。

    スペック

    簡単に今のぼくの環境をご紹介。

    MacOS X
    Lion
    Java
    1.6.0_29
    Titanium SDK
    1.8.2
    Titanium Studio
    1.0.9


    requireをAndroidで使えるようにするため、tiapp.xmlにfastdevを無効にするタグを追加

    CommonJSでコーディングする際、requireで外部のJavaScriptファイルを読み込むことが非常に多くなりますが、
    このパスがfastdevを有効にしているとうまくいかない。
    Titanium mobile -- Android でrequire()エラー - WEBサービス 情報局

    Androidの場合だけですが、

    が「Resources/lib/lib/a.js」のようになってしまう。
    これは、Titanium1.6までのTi.includeと同じ現象かなーと思っています。
    libの階層が一個多い!!
    Titaniumのインクルードパスを指定する方法私案 - もぎゃろぐ

    なので、以下のように非常に残念ですが、fastdevを無効にするタグをtiapp.xmlに入れましょう!

    1.8現在、まだこのバグが直っていないので、今後に期待ですね。
    とはいえ、Androidのデバッグは以下で紹介しますが、DDMSというツールを使って実機で行なっているので、
    fastdevの恩恵はそもそも受けられなかったです。


    アプリのバージョンを取得する方法

    tiapp.xmlの

    に書いたのアプリバージョンになります。
    そして以下が取得コード

    アプリを段階的にリリースする際などに、このバージョンを見て処理を分けたりできますね。

    [via]
    Office L テクニカルノート


    JSSはプロジェクトをcleanしないと修正したものが反映されない問題!とかあといろいろ

    以下が簡単なJSSサンプル。

    app.js

    app.jss

    こちらのJSSファイルに記述したCSSっぽいものが、この場合はidに紐づいて反映されるが、
    プロジェクトのcleanをしないと反映がされない。
    つまり以下のredをblackにしてRunしなおしても反映されないのだ。

    TitaniumのJSSという機能 | ひげろぐの記事を読むと1.6で修正されたとあるので、もしかしたら1.8で再度このバグが出たのかな?

    また、以下の記事を読むとやっぱりまだJSSを使うときじゃないのかなーと思っています。1.6の記事ではありますが。
    Titanium Mobile でCSS的な、それJSS!!!!!! | MOL

    なので、Zaimで採用されているTitanium でつくろう! iPhone/Android 両対応アプリのような方法よいかもしれません。
    (この方法すばらしいと思います!)


    iPhoneの場合CommonJSのrequireで呼び出されたモジュール内でグローバル変数が見れる

    以下のようなシンプルなサンプルでiPhone、Androidで試してみましたが、
    iPhoneの場合にhogeがtestmodule内から見えてしまいました。

    一応node.jsで同じことをやってみましたが、hogeが見えなかったです。

    app.js

    testmodule.js

    以下の和訳ページを見てみると、

    TiにおけるCommonJSモジュールの仕様の実装はnode.jsのものに基づいています。


    via: CommonJS Modules in Titanium - JP::HSJ::Junknews::HatenaSide

    アプリケーション内のすべてのモジュールにわたって共有されるグローバル変数は存在してはいけません。


    via: CommonJS Modules in Titanium - JP::HSJ::Junknews::HatenaSide

    と書いてあることから、このパターンだとiPhoneの場合のrequireがヘンテコなことになっているのかな?
    なので、無名関数で囲ってあげる。

    Androidのエラー内容

    DDMS(↓のほうで解説)で調べた内容。

    02-27 14:46:27.499: E/TiJSError(2137): (main) [311,706] ----- Titanium Javascript Runtime Error -----
    02-27 14:46:27.499: E/TiJSError(2137): (main) [1,707] - In testmodule.js:5,36
    02-27 14:46:27.499: E/TiJSError(2137): (main) [0,707] - Message: Uncaught ReferenceError: hoge is not defined
    02-27 14:46:27.499: E/TiJSError(2137): (main) [0,707] - Source: Ti.API.log('aaaaaaaaaaaaaaaa: ' + hoge);
    02-27 14:46:27.539: E/V8Exception(2137): Exception occurred at testmodule.js:5: Uncaught ReferenceError: hoge is not defined

    iPhoneのエラー内容

    無名関数でapp.js内を囲うと以下のエラーが出た。

    [ERROR] Script Error = Can't find variable: hoge (unknown file).

    ■参考リンク
    CommonJS Modules in Titanium - Documentation & Guides - Appcelerator Wiki
    俺流コーディングスタイルにダメ出し - toweroflの日記
    Titanium Mobile Best Practices - JP::HSJ::Junknews::HatenaSide


    TextMate風なスニペットで楽々開発!

    20111205233655.png

    [via]
    【Titanium Advent Calendar 2011:八日目】タイタにうもん第1話 - JP::HSJ::Junknews::HatenaSide

    このスニペットのおかげで、buttonと入れてtabを押せばビヨッと展開されるし、webviewって入れてもいいし、infoって入れてもいいしね。
    このコード補完は非常に強力です!(どうしてcreateWindowはないんだろう。)


    .svnディレクトリが悪さするから、gitを使おう?

    以下の記事によると、

    私みたいに、会社の都合等で、gitが使えずにSVN使っている方いますよね。
    なんと、TitaniumStudioにて、SVNチェックアウトしたAndroid用プロジェクトを、RunやDistributeしようとすると、失敗しちゃいます><。
    画像の生成のところで失敗しているみたいですね><。


    via: 【Titanium Advent Calendar 2011:十日目】

    となっていて、svn exportしてからbuilder.pyを呼び出すということをされています。
    ちょっと僕のほうで確認ができていないのですが、確かにすべてのディレクトリに.svnがいるのはちょっといやだなーと思うので、思い切ってgitを採用しちゃうのもありですね。

    こちらSession01 - Android バットノウハウつめあわせ on Vimeoでも同じようにgitを使おうって話しになっていて面白かったです。


    アプリ名の変更はプロジェクトの作り直しが楽?

    Androidだと、

    02-27 19:48:11.943: E/AndroidRuntime(6196): java.lang.RuntimeException: Unable to instantiate application com.hisasann.Hoge.HogeApplication: java.lang.ClassNotFoundException: com.hisasann.Hoge.HogeApplication in loader dalvik.system.PathClassLoader[/data/app/com.hisasann.Hoge-1.apk]
    02-27 19:48:11.943: E/AndroidRuntime(6196): at android.app.LoadedApk.makeApplication(LoadedApk.java:466)
    02-27 19:48:11.943: E/AndroidRuntime(6196): at android.app.ActivityThread.handleBindApplication(ActivityThread.java:3287)
    02-27 19:48:11.943: E/AndroidRuntime(6196): at android.app.ActivityThread.access$2200(ActivityThread.java:121)

    が出る。

    【Titanium Advent Calendar 2011:一日目】既にリリースしたアプリ名の変更(AppStore編) | MOL
    にあるリンク先に、

    Because of generated files and complexity with renaming some of them, we decided against allowing editing. You can create a new project and just copy in your Resources to the new project (and then just delete old).


    via: How can i rename my iphone app project? » Community Questions & Answers » Appcelerator Developer Center

    と書いてあるので、たしかにへんなエラーで(ClassNotFoundException)で悩むぐらいなら、新しくプロジェクト作ってリソースコピーしちゃえ!


    ファイル名にアンダースコアが付いているとAndroidの実機にインストールできない

    Titaniumでアンダースコア付きのファイルはやめておいたほうがよいみたい。

    [ERROR] /TitaniumStudioWorkspace/Sample-LocalJqm/Resources/jqm/js/jquery.mobile-1.0.1/demos/docs/_assets/js/_viewsource.js is an invalid filename. Android will not package assets whose filenames start with underscores. Fix and rebuild.

    このようにjquery.mobile-1.0.1の下にあるdemoディレクトリ内にアンダースコア付きのファイルがあって、iPhoneだと実機にインストールできますが、Androidでは入らない。

    [via]
    pd @ blogger: Titanium Mobile 1.8 からの変更点?ビルドが進まない。
    (こちらの記事のV8が速いという記事、ちょっとグッときました)


    ローカルHTMLの場合historyが記録されないのでjQueryMobileの戻るボタンは反応しない

    httpで読み込むなどした、外部のサイトならOK!
    ローカルHTMLの場合は、戻るボタンを押してもうんともすんともいってくれない。

    [via]
    Titanium の WebView で HTML をホスト | アカベコマイリ


    Ti.Media.showCamera(カメラ)を使ってみる

    古いバージョンではAndroidの場合に、tiapp.xmlに以下のようにパーミッションを追記する必要があるかもしれません。
    現時点で検証している1.8.1と1.8.2では、デフォルトでAndroidのカメラパーミションがもれなく付いてきています。

    iPhoneは特になんの設定もしなくても使えます。

    ■カメラを使ったサンプルコード
    TitaniumMobileでカメラを使う方法 -- Gist

    ちなみにここで、カメラのパーミションを追記していますが、僕個人としては、のちのちのことを考えると次でご紹介するAndroidManifest.xmlに追記する方法をおすすめします。


    Xperia arcでカメラを使うと予期せぬ強制終了が発生する

    Androidのバージョンは2.3.2だが、何をどうしてもカメラを撮影したタイミングで落ちてしまう。
    具体的なコードは以下のとおり。
    至って普通のカメラ呼び出しだが、この引数に渡しているオブジェクトのプロパティをいろいろいじってみたが100%落ちる
    Xperia arcは比較的シェアが高めな端末なので、こうなるとカメラの機能は自前でモジュールとして作成するか、必要がないなら使わないなどの対策が必要が気がしています。

    [#TIMOB-4899] Camera crashes Sony Ericsson Xperia Arc Android 2.3.2, 2.3.3 with all branches - Appcelerator JIRA

    Androidが落ちた時のエラー

    02-21 09:59:02.214: E/TiApplication(17570): (main) [681,31285] Sending event: exception on thread: main msg:java.lang.RuntimeException: Failure delivering result ResultInfo{who=null, request=1, result=-1, data=Intent { act=inline-data dat=file:///sdcard/dcim/Camera/tia-1288732183.jpg typ=image/jpeg (has extras) }} to activity {com.hisasann.Baruth/org.appcelerator.titanium.TiActivity}: java.lang.NullPointerException; Titanium 1.8.1,2012/01/27 17:31,a24502a
    02-21 09:59:02.214: E/TiApplication(17570): java.lang.RuntimeException: Failure delivering result ResultInfo{who=null, request=1, result=-1, data=Intent { act=inline-data dat=file:///sdcard/dcim/Camera/tia-1288732183.jpg typ=image/jpeg (has extras) }} to activity {com.hisasann.Baruth/org.appcelerator.titanium.TiActivity}: java.lang.NullPointerException
    02-21 09:59:02.214: E/TiApplication(17570): at android.app.ActivityThread.deliverResults(ActivityThread.java:2504)

    どうもintentまわりでヌルポが発生しているように見える。
    なんとなくだが、

    Sony Ericsson Xperia Arc has a branded Android version, and a special camera (also camera software).


    via: [#TIMOB-4899] Camera crashes Sony Ericsson Xperia Arc Android 2.3.2, 2.3.3 with all branches - Appcelerator JIRA

    と書いてあるとおり、もしかしたらarcはカメラのアプリが特殊なので、intentに失敗しているのかも?


    AndroidManifest.xmlにAndroidの設定を追記してみる

    Androidの設定は、AndroidManifest.xmlファイルに書き出されます。
    細かい部分は、a. AndroidManifest.xml ファイル - ソフトウェア技術ドキュメントを勝手に翻訳を参照ください。

    んで、このファイルがTitaniumの場合どこにあるかと言いますと、

    /[プロジェクト名]/build/android/AndroidManifest.xml

    になります。

    一度でもAndroidでビルドしているとこのファイルができていますので、試しに見てみましょう!

    下のほうにいくと

    と書かれていますね。
    つまり、TitaniumMobileの場合は、デフォルトでカメラが使える状態なのです。

    この場所に置かれているAndroidManifest.xmlはビルドするたびに作りなおされてしまいますので、
    プロジェクト内に配置して、うまいことマージしてもらいましょう。

    TitaniumStudioから以下のディレクトリに↑のファイルをコピーする。

    /[プロジェクト名]/platform/android/AndroidManifest.xml

    これで、ビルド時にここのファイルを見に行ってくれるので、Android特有の設定はここに追記していく。
    tiapp.xmlに書いていく方法もあるようなのですが、実はあんまりよく理解できませんでした。
    そして、最終的にこっちに書かないとうまくいかない設定があったりなどで、このスタイルに落ち着いています。


    iPhoneとAndroidでwidthなどのサイズの指定をどうするか

    これはまだ最終的な策が出ていませんが、現時点でこうかなーという感じで書いてみます。
    そもそもの話しですが、たとえばwidth:'320px'とこれは、400pxではなく300pxでもなく320pxです。
    つまりiPhoneでは横幅いっぱいですが、他のAndroidなどは画面の中央ぐらいまでの場合もあります。

    これだと各端末の場合はというif文が存在してしまい、とてつもなく大変なことになります。
    これをうまいこと吸収してくれる?のがdp(だと思います)

    Y.A.M の 雑記帳: Android multi screen 対応
    を参考にさせていただいて、AndroidManifest.xmlに追記しました。

    そして、プログラム内でサイズを指定する箇所は「width : '320dp'」のようにdpと指定しています。
    dpに関する内容は、以下が詳しかったです。

    画面の物理的な密度に基づいた抽象的な単位。
    この単位は 160 dpi の画面と対応していて、160 dpi の画面で 1 dp = 1 px になる。なので、dp-pixel 比は画面密度(解像度)に応じて変化するが、必ずしも正比例するわけではない。


    via: Y.A.M の 雑記帳: Android Dimension 単位

    dpiが160の場合は320dpは320pxなんですが、このdpiが変わって240になると320dpが480pxになったりします。

    ちょっとだけ厄介なのが、iPhoneのエミュレータは160dpiですが、iPhone4Sの実機で試したところ320dpiが返ってきました。
    なんというRetina Displayよ!


    dp指定の場合のanimateはどうしよう

    Titaniumのアニメーションは非常に便利で、以下のように書くだけで動いてくれます。
    jQueryみたい!

    ここで問題なのが、heightやtopなどにはInt値しか渡せないことです。
    つまり、

    はエラーになります。
    これを回避するために、以下のようなコードを書きたいところですが、iPhone4Sだとdpiが320なので、320dpを渡すと640が返ってきてしまいます。

    現時点ではAndroidの場合に上記コードを実行するようにしていますが、果たしてiPadでうまいこといくのかどうか。
    今後、確認します。


    アプリを縦向き固定(portrait)のみにする

    iPhoneの場合は、tiapp.xmlに以下のように記述すればよいのですが、

    Androidは、AndroidManifest.xmlに記述します。
    これは結構ネットでもいろんな記述されている方が多く、またそれらが古いバージョンでは動くが現バージョンでは動かないなどがあり結果このスタイルに落ち着きました。

    ■最終的なAndroidManifest.xml
    AndroidManifest.xmlのサンプル、縦固定などなど。 -- Gist

    ちなみにJavaScriptからもできるようです。

    ただ、気をつけることはTitanium.UI.createWindowするときには指定せず、そのあとにorientationModesをセットしないとダメのようです。
    むむっ!


    存在しないオブジェクトプロパティの値がiPhoneとAndroidで異なる

    以下のようなコードを書いたときにiPhoneとAndroidで結果が異なる。

    iPhoneの結果

    [INFO] <null>

    Androidの結果

    03-05 09:23:05.243: I/TiAPI(5644): undefined

    とはいえ、

    という書き方すれば大丈夫ですね。

    [via]
    Session01 - Android バットノウハウつめあわせ on Vimeo


    Androidの場合HttpClientとWebViewでcookieが共有されない

    以下のようのPHPコードでCookieの共有検証をしてみました。

    クッキーにセットした値をカウントアップします。 -- Gist

    結果、

    • iPhoneは共有される。ただし、アプリをkillするとCookieは消去される。
    • Androidは共有されない

    Androidのほうの共有されない問題は、じつは結構でかい問題で、特にログイン機能を持っているアプリの場合に厳しいと思います。
    これみなさんどうしてるんですかね。

    なので、CookieよりはTi.App.Propertiesを使うほうが確かかもしれません。

    [via]
    Session01 - Android バットノウハウつめあわせ on Vimeo


    httpsなサイトをWebViewで開く場合は証明書が大事!

    httpsなURLにアクセスする際にオレオレ証明書だとアクセスすることができません。
    その挙動がiPhoneとAndroidで違うので以下にメモ。

    iPhoneで接続した場合

    ちゃんとcertificateのエラーが出てくれる。

    [ERROR] Error loading: https://hogehoge.com/, Error: Error Domain=NSURLErrorDomain Code=-1202 "The certificate for this server is invalid. You might be connecting to a server that is pretending to be "hogehoge.com" which could put your confidential information at risk." UserInfo=0xa812dd0 {NSErrorFailingURLStringKey=https://hogehoge.com/, NSLocalizedRecoverySuggestion=Would you like to connect to the server anyway?, NSErrorFailingURLKey=https://hogehoge.com/, NSLocalizedDescription=The certificate for this server is invalid. You might be connecting to a server that is pretending to be "hogehoge.com" which could put your confidential information at risk., NSUnderlyingError=0x8c315f0 "The certificate for this server is invalid. You might be connecting to a server that is pretending to be "hogehoge.com" which could put your confidential information at risk.", NSURLErrorFailingURLPeerTrustErrorKey=}

    Androidの場合

    何もエラーが出ず、画面にHTMLも表示されない。
    つまり一見するとハマる。


    Ti.Network.createHTTPClientで証明書がないhttpsを開けるけども?

    以下のようにTitanium.Network.HTTPClientのvalidatesSecureCertificateというプロパティをfalseにすると、証明書がないhttpsなURLでも通信することができる。

    ただし、

    validatesSecureCertificateはシミュレータや実機テスト時はfalseだけど、リリース用の時は強制的にtrueなのかな? / "Does titanium mobile supports SSL with htt..."


    via: Twitter / @hisasann: validatesSecureCertificate ...

    なんか自分でもつぶやいていますが、
    Does titanium mobile supports SSL with https URLs ? » Community Questions & Answers » Appcelerator Developer Center
    によると、デプロイするとデフォルトtrueで上書きができないんじゃないかなーって思っています。(未検証)

    アプリ開発ではこのhttpsなんだけど証明書がないケースでのテストができないこともあるので、
    ちょっとテストがしにくいですね。


    WebViewとTitaniumの連携 - ローカルHTML(アプリ内HTML)からTitaniumのイベントをfire

    app.jsの一部

    WebViewで読み込まれたローカルHTMLの一部

    ちなみにですが、リモートのHTMLをWebViewに読み込んだ場合は、上記コードは動かない。
    あたりまえですが、勝手にexternalなサイトからアプリ内のイベントを呼ばれちゃうのは困る。

    場当たり的にいろんな名前でイベントfireしまくれば、もしかしたら一個ぐらいは動くかも?

    ただし、HTML 内から Titanium オブジェクトを呼び出すのは、ローカルに保存された HTML でないといけません。


    via: MountPosition Inc. » TitaniumでWebView にイベントリスナを登録する

    ■参考リンク
    Titanium の WebView で HTML をホスト | アカベコマイリ
    addeventlistener - Trouble using Titanium's webview to fire an API event - Stack Overflow
    WebViweに表示されているHTMLからTitaniumの処理を実行する | ひげろぐ


    WebViewとTitaniumの連携 - Titaniumから読み込んだHTMLを操作する

    WebViewにロードしたHTMLをload後に書き換える方法

    これはコードで見たほうが早いですね。

    app.js

    WebView.js

    TitaniumMobileでWebViewを使う方法 -- Gist

    上記の、

    で行なっています。
    ただし、まだ僕もよく分かっていませんが、構文にミスがあっても、うんともすんともエラーを出してくれません。
    よって、デバッグがかなり大変になります。
    なので、この処理はあくまでもヘッダー・フッターをdisplay:none;にしたいなど、
    そういった比較的軽めな対応にしておいたほうがよさそうです。

    また、このevalJSは複数行のコードを評価させると、1行目しか実行してくれません。(Androidの場合だけっ!)
    つまり、以下のコードを実行すると、

    alertは出ますが、テキストボックスの値は変わりません。
    セミコロン1個までじゃないとダメなので、もし複数行のJavaScriptを実行する場合は、

    と書くようです。
    難しい!

    [via]
    【Titanium Advent Calendar 2011:二日目】evalJSの恐怖 - もぎゃろぐ


    adbコマンドでAndroidデバイスを知る!

    接続されているAndroidデバイスの確認は、

    adb devices

    ログは、

    adb logcat

    複数接続されている場合は、デバイス番号を指定する。

    adb -s [デバイス番号] logcat

    [via]
    複数デバイスが動いているときにログを見る - ore*flow


    AndroidのWebViewではlocalStorageが使えない

    いろいろ試していてハマったんですが、AndroidのWebViewでlocalStoragenullになってしまう。
    WebViewではなくブラウザではOK。

    調べていくと、ネイティブだと以下のようなコードをWebViewを呼ぶ前にする必要があるみたい。

    [via]
    Android WebView で HTML5 の Web Storage と Web SQL Database API を使う - nobnakの日記

    でも、この設定をできるコードがTitaniumに見つからない。

    以下のようにいろんな人たちがハマっていて、これは今後どうなるんだろう。
    Localstorage failure in webview » Community Questions & Answers » Appcelerator Developer Center
    Webview - Enabling localStorage » Community Questions & Answers » Appcelerator Developer Center
    how to enable localStorage iun Android » Community Questions & Answers » Appcelerator Developer Center
    Twitter / @hisasann: AndroidのWebViewでlocalStora ...

    外部サイトを読み込み、かつlocalStorageを使いたい場合は、Titanium.Platform.openURLブラウザを開いてあげるしかないのかな。
    あとはTitanium.App.Properties.setStringを使ってなんとか、アプリ側に値を保持して、うまいことやる?
    ちょっとややこしいですな。


    Titanium-Google-Analyticsでトラッキング

    rogchap/Titanium-Google-Analyticsを使ってできるようです。(未検証)

    こちらの記事が参考になります。
    Titanium MobileでGoogle Analyticsを利用する - box box box


    Ti.Appにグローバルな変数を入れて共有する

    引数で渡すよりもグローバル化したほうが効率的なシチュエーションがあるので、Ti.Appにいろいろぶらさげて管理したいところ。
    ただ、Ti.App配下にはすでにたくさんのプロパティやらメソッドがあるので、これらを壊さず、かつ、開発者が追加したというのが分かるようにしたい。

    ということで、

    みたいに、一つワンクッションを入れて、プロパティを管理しようと思いました。
    ところが、

    としても、hogeがnullのままになるという減少に悩まされました。
    なので、以下のコードで検証。

    なんだこれ。。。
    なので、function(){}を使って名前空間を作っています。

    ちなみにですが、名前空間を使わず、以下のように入れれるので、面倒な方は以下の方法ですかね。

    [via]
    Ti.Appにオブジェクトをくっつけてグローバル変数的に使う | ひげろぐ


    僕のiPhone、Androidのデバッグ環境

    本来ならiPhoneもAndroidもエミュレータを起動して確認して、その後に実機に入れて確認という感じになるとは思うのですが、
    僕の環境ではAndroidエミュレータを起動した際(ランダム)にMacが強制的に落とさないといけない状況になります。
    具体的にどうなるかはInstagramこちらをご覧ください。
    (どうやらカーネルパニックのようです)
    Androidエミュレータを起動したときのMacのエラーログ -- Gist

    それに、↑のほうで解説したようにfastdevを使った状態だとrequire時のパスがヘンテコになります。
    もう、これだけ揃うとエミュレータで作業する意味があまりないので、実機でのデバッグになります。

    ちなみにですが、エミュレータの起動は死ぬほど重いですが、実機への転送は意外と速いです。

    Androidのデバッグについて

    会社の方に教えていただいたのが、このDDMSという付属ツール。
    以下の場所にあります。(Androidを触り始めて1週間でこのツールの存在を知りました!遅い!)

    android-sdk-macosx/tools/ddms

    僕は、しょっちゅう使うので、aliasにして.bash_profileに書いちゃいました。

    alias ddms="~/_/dev/android-sdk-macosx/tools/ddms"

    ■参考リンク
    AndroidのDDMSの使用方法のドキュメントを翻訳しました - Android(アンドロイド)情報-ブリリアントサービス

    Androidの実機をMacに接続し、あとはRunのボタンのAndroid Deviceを選んでちょいとまちます。
    すると、

    [INFO] Application installed. Launch from drawer on Home Screen

    と出るので、Androidのアプリのところから自分のアプリを起動します。
    ここで、ちょっとしたことではなりますが、僕はTi.API.logではなくTi.API.errorを使ってログを吐くようにしています。
    logほうでもいいんですが、流れるスピードが尋常じゃないので、errorで出力しておいて、
    DDMS側のログレベルをerrorにしています。

    それかSaved FiltersのところでFilterを作っちゃうかですね。

    もっといい方法があるだろう。

    iPhoneのデバッグについて

    iPhone側はなんの問題もありません。
    エミュレータでガシガシ開発しています!
    しかもエミュレータ起動速い!いいね!


    Jasmineを使ってテストをする

    すでにあるguilhermechapiewski/titanium-jasmineこちらをCommonJS対応し、ディレクトリ構成を綺麗にした版

    hisasann/titanium-jasmine

    を作ってみました。

    普通に起動したいなら、

    make run-iphone

    テストとして起動したいなら、

    make test-iphone

    クリーンしてから起動したいなら、

    make clean && make run-ipad

    TitaniumStudioから普通に起動しても問題ありません。


    TitaniumMobileで作られたアプリ

    1. Zaim
    2. はてなカウンティング
    3. 積ん読本
    4. Wunderlist
    5. Nyars
    6. そうしてあなたはさっていくのね
    7. POPCORN S
    8. NIFTY-Serve
    9. Sptted
    10. MogSmash(MogSnapって今動かないですよね?)

    こちらにかなりまとまっています。
    Titanium Mobileの開発事例 « Titanium BBS(JP unofficial)


    是非読んでいただきたい記事やスライドや動画やコード!

    小さな Titanium Mobile の読み物

    JavaScriptを使って一週間でiPhoneアプリを作ってみた。 - おんがえしの日記

    Session06 - TitaniumでiOS/Android同時リリース:NIFTY-Serveの事例 from astronaughts on Vimeo.

    Session07 - MogSnap 開発秘話&すぐに使える Titanium アニメーションテク from astronaughts on Vimeo.

    toru0325/TKAnimationSample

    toru0325/TiMetro - GitHub


    まとめ

    とにかくハマる!
    ハマる!
    ハマる!

    でも、ふと思ったんですが、そりゃiPhoneとAndroidの両方をJavaScriptで開発し、かつ同じコードでもそこそこ動く環境という時点で非常にありがたい。
    あとはUIを分けるなどして、分岐していくのかなーと思いますが、iPhoneではアニメーションすごくいい!Androidだとそこそこいい!なので、これから流行ってきそうですね。

    Titanium Mobile 2.0リリース発表を東京でも行います! 詳細は後日公開しますが4/20の予定となっています!参加しようかな?と思う方はFavを頂けるとうれしいです!


    via: Twitter / @masuidrive: Titanium Mobile 2.0リリース発表を ...

    TitaniumMobile2.0期待!

    Titanium Mobileで開発するiPhone/Androidアプリ (Smart Mobile Developer)
    北尾 雅人
    翔泳社
    売り上げランキング: 11403

    TortoiseGitとmsysgitではじめるWindowsGit生活

    Windowsにgitを入れたことがなかったので、比較的ラクに導入する方法をいろいろ調べてみたところ、TortoiseSVNならぬTortoiseGITがあったので、これの導入までをメモ。

    このTortoiseGITを使えば、コードとか書かないけどWindows上でgit使わないといけなくなってしまったPMさんとかデザイナーさんでも安心してgitを使うことができると思います。

    TortoiseGitを使うには、msysgitというツールをインストールする必要があります。
    このmsysgitがgitの実体です。
    その昔、Cygwinを入れて、gitを使うという方法があったようですが、今はこのツールだけあればgitが使えます。(日本語が使えないですが)

    msysgitのインストール

    InstallMSysGit · msysgit/msysgit Wiki

    以下から、msysGit-fullinstall-1.7.9-preview20120201.exeをダウンロードします。
    Downloads - msysgit - Git for Windows - Google Project Hosting

    展開先を「C:\msysgit」のままにして実行しました。
    もし他のパスがよい場合は適宜変更してください。

    Windows 7 x64.png

    すると、上の画像のようなコンソールが出てきます。
    これでインストールは完了だとは思うのですが、

    InstallMSysGit · msysgit/msysgit Wikiに書いてある以下のシェルを実行しときました。

    /share/msysGit/initialize.sh

    このmsysgitの面白いところが、Unixコマンドが打てることです。
    llとかpwdとかUnix上で使っていたコマンドが使えます。

    サイドこのプロンプトを開きたいときは、

    C:\msysgit\msysgit\msys.bat

    を実行します。
    なので、このファイルのショートカットを作っておくと便利かもしれません。

    あと、msysgitはssh-keygenが使えます!

    gitの設定ファイル「.gitconfig」の場所

    C:\Users\hoge\.gitconfig

    ここにおいてあります。

    せっかくなので、コンソールからグローバルなユーザー名とメールアドレスを設定しちゃいましょう。
    msys.batを起動して、以下のコマンドを打ちます。
    ユーザー名とメールアドレスは適宜読み替えてください。

    git config --global user.name "hoge"
    git config --global user.email "hoge@hoge.com"

    では環境設定を表示してみましょう。

    git var -l

    user.nameuser.emailがちゃんと反映されています。

    core.symlinks=false
    core.autocrlf=true
    color.diff=auto
    color.status=auto
    color.branch=auto
    color.interactive=true
    pack.packsizelimit=2g
    help.format=html
    http.sslcainfo=/mingw/bin/curl-ca-bundle.crt
    sendemail.smtpserver=/mingw/bin/msmtp.exe
    diff.astextplain.textconv=astextplain
    rebase.autosquash=true
    http.proxy=
    user.name=hoge
    user.email=hoge@hoge.com
    core.repositoryformatversion=0
    core.filemode=false
    core.bare=false
    core.logallrefupdates=true
    core.symlinks=false
    core.ignorecase=true
    core.hidedotfiles=dotGitOnly
    remote.origin.fetch=+refs/heads/*:refs/remotes/origin/*
    remote.origin.url=c:/_/dev/gittestrepos/test.git/
    branch.master.remote=origin
    branch.master.merge=refs/heads/master
    GIT_COMMITTER_IDENT=hoge hoge@hoge.com 1331271139 +0900
    GIT_AUTHOR_IDENT=hoge hoge@hoge.com 1331271139 +0900
    GIT_EDITOR=vi
    GIT_PAGER=less

    TortoiseGITのインストール

    tortoisegit - Porting TortoiseSVN to TortoiseGIT - Google Project Hosting

    以下から、TortoiseGit-1.7.7.0-64bit.msiをダウンロードします。
    32bitな方は、32bitのほうをダウンロードしてください。
    Downloads - tortoisegit - Porting TortoiseSVN to TortoiseGIT - Google Project Hosting

    TortoiseGitのインストール時には使用するSSHクライアントを設定するが、GUIメインで利用するなら「TortoisePLink」を利用する設定にすると使い勝手が良いだろう


    via: 実用レベルに達したWindows向けGitクライアント「TortoiseGit」でGitを始めよう - SourceForge.JP Magazine : オープンソースの話題満載

    これを呼んだので、特に何も迷わずに次へ次へと進んでみました。
    これでインストールは完了。
    すごく簡単!

    ちなみに、msysgitのコンソールから「git commit -m 'テスト'」のように日本語を入力することができません。
    ですが、TortoiseGITからのcommitでは日本語が通るので問題ありませんね。

    あとは、使って慣れる!
    git - 簡単ガイドとか読んで慣れる!

    番外編 - リモートリポジトリをローカルに配置してちょっとしたバージョン用にgitを使ってみる

    僕はブログの記事(比較的長文)を書くときは、間違えてファイルを消したりしたとき用にgitを使ってバージョン管理しています。
    一般的にはローカルのリポジトリで作業して、リモート(別のサーバーや端末)に対してpushすると思うのですが、そこまでしないけどバージョンしたいときに以下のようにして使っています。

    ローカルでリポジトリを作成する

    % cd 適当なディレクトリ
    % mkdir gittest
    % cd gittest
    % git init

    % touch README
    % git add README
    % git commit -m 'first commit'

    ローカルでリモートリポジトリを作成する

    % mkdir /c/gittestrepos/gittest.git
    % cd /c/gittestrepos/gittest.git
    % git --bare init

    ローカルからローカルにあるリモートリポジトリにpushする

    % cd 適当なディレクトリ
    % git remote add localrepos /c/gittestrepos/gittest.git
    % git push localrepos master

    上記ではmsysgitを使ってやってみました。
    /c/というのがCドライブになります。

    このように別にリモートだからといって、別の端末になくてもいいんですよね。
    このあとに、もしgithubにコミットしたいと思ったときはremoteをaddすればよいので、楽チンかなーと思います。

    ■参考リンク
    Git/一人で使ってみる(msysgit編) - 俺の基地
    Git/インストール(WindowsXP編) - 俺の基地
    msysgitインストール 〜 sshでのgitリポジトリアクセスまで | Happy my life
    せっかちな人のための git 入門 - git をインストールし、共同で開発できる環境を整えるまで - 僕は発展途上技術者

    Gitによるバージョン管理
    岩松 信洋 上川 純一 まえだこうへい 小川 伸一郎
    オーム社
    売り上げランキング: 24163

    githubのgh-pagesブランチを使って自作サイトを表示する方法

    こちらの30分、JavaScriptで作るWebサービスのモックアップ - ゆーすけべー日記記事を拝見して、僕もざっくりとしたInstagramAPIを使ったサイトを作ってみた。

    ひたすらラーメンの写真を表示するInstagramサイト - Ramenstagram

    Ramenstagram

    ひたすらBlackMilの写真を表示するInstagramサイト - I Love BlackMilk!

    I Love BlackMilk!

    またくだらないものを・・・

    githubリポジトリを作る

    ではではまずはgithubのリポジトリを作りましょう!

    githubでリポジトリを作り、ローカルで以下のように実行する。
    基本的なgithubの手順ですね。

    mkdir Ramenstagram
    cd Ramenstagram/
    git init
    touch README
    git add README
    git commit -m 'first commit'
    git remote add origin git@github.com:hisasann/Ramenstagram.git
    git push -u origin master

    gh-pagesブランチを作成する

    GitHub Pages - Homeに書いてあるとおりですが、以下のようにコマンドを実行してブランチを作成します。

    cd Ramenstagram/
    git symbolic-ref HEAD refs/heads/gh-pages
    rm .git/index
    git clean -fdx
    echo "My GitHub Page" > index.html
    git add .
    git commit -a -m "First pages commit"
    git push origin gh-pages

    これでgit branchしてみると、

    * gh-pages
    master

    となっているので、現在作業中のブランチは「gh-pages」ということになる。

    githubサイトにて

    adminボタンをクリック。

    すると以下の画像のように、すでにGitHub Pagesが作られていて、チェックボックスにチェックが入っている。
    これは、gh-pagesというブランチを作ると自動的にチェックが入るよう。
    逆にgitコマンドからではなく、adminページにて、チェックを入れても同じようにgh-pagesブランチが作られる。
    どっちが楽かはあなた次第!

    Administration for hisasann_Ramenstagram - GitHub.png

    そして、
    http://hisasann.github.com/Ramenstagram
    にアクセスしてみると、ちょっと待っててよ的な画面が。

    GitHub Pages - File Not Found - GitHub-2.png

    少し時間を置くと以下のようにindex.htmlの内容が表示された!

    GitHub Pages - File Not Found - GitHub-1.png

    あとは、このブランチに自分のサイト用のHTMLやらJavaScriptやらCSSやらを配置してコミットすれば自動的に反映される!
    便利!

    InstagramのtagAPIを使ってJSONを返すnode.jsコード

    ちなみにInstagramのJSONを取得しているのはnode.jsで作っています。

    フロントのJavaScriptだけで完結したほうが綺麗なんですが、access_tokenをバレたくないので、いったんこのnodeがプロキシになってInstagramのtag情報から画像を返すようにしています。

    InstagramのtagAPIを使ってJSONを返すnode.js版プロキシー -- Gist

    ■参考リンク
    実践GitHub Pages運用のユースケースとワークフローの詳細 | ゆっくりと...
    GithubのProject Pagesを作る手順を調べてみた。もしくはgitで空ブランチを作る方法を調べてみた。 - kanonjiの日記

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

    クロスドメイン用のHTTPレスポンスヘッダー - Perlスクリプト版

    iPhoneのSafariとAndroidのブラウザ、PCのSafariとChromeでクロスドメインなAjaxを行う場合のレスポンスヘッダーで地味にハマったので、忘れないうちにメモしとく。

    たいていの場合、.htaccessファイルに「Access-Control-Allow-Origin: *」を含めておけばいけまっせー!的な感じで書かれている場合が多いが、CGIとして書く場合にはもう1個だけ重要なものがあります。

    それが、

    Content-Length

    !!

    Content-Lengthが正しくないとAndroidのブラウザPCのChromeでAjax通信でレスポンスが返ってきてくれない。
    まぁ、あんまりCGIとして書くケースはないのかもしれないのですが、.htaccessを使えないときには有効かもしれません。

    Perlのコード

    大体こんな感じでJSONを返すCGIを書いたときに、「Access-Control-Allow-Origin: *」と「Content-Length」 を正確に返す必要がある。
    なので、以下コードでうまくいく。

    Ajaxアクセス用のコード

    こっちはこれだけ。
    IEを考慮していないので、XDomainRequestは無視しています。


    また、ちょっと古い記事ですが、クロスドメインなAjaxに対応したブラウザをご覧になりたい場合は、XMLHttpRequest level2に対応しているブラウザまとめをば。

    初めてのPerl 第5版
    初めてのPerl 第5版
    posted with amazlet at 12.02.15
    Randal L. Schwartz Tom Phoenix brian d foy
    オライリージャパン
    売り上げランキング: 30529

    MacOSX LionにPhoneGapをインストールしたときのメモ(2012-02-09時点) - iPhone/Android対応

    PhoneGap.png

    iPhone版

    PhoneGapもTitanium Mobile同様、結構ググると情報が古い。
    特にXCodeが3から4に上がったとこで、かなりUIも変わっているので、昔の情報はあんまり役に立たない。

    なので、PhoneGapのサイトにあるGet Started Guideを見ながらいろいろ試してみました。
    Get Started Guide « PhoneGap

    PhoneGapをダウンロードする

    Download « PhoneGapよりDownloadボタンをクリックし、PhonGapをダウンロードします。

    現時点(2012-02-07)では1.4.1のようです。
    zipファイルを解凍します。

    PhoneGapをインストールする(iOS版)

    以下のディレクトリのdmgファイルをダブルクリックします。

    /phonegap-1.4.1/lib/ios/PhoneGap-1.4.1.dmg

    すると、PhoneGap-1.4.1.pkgファイルが出現するので、次へ次へを押してインストールします。

    XCodeでPhoneGapプロジェクトを作成する

    XCodeのメニュー「File→New→New Project」を選択します。
    以下のようにPhoneGapプロジェクトを選択し、プロジェクトを作成します。

    Xcode-2.png

    "Product Name"と"Company Identifier"を入力します。
    とりあえず、僕は以下の感じでやりました。
    Company Identifierはご自分のBundle identifierを入力してくださいね。
    (ゆくゆく実機で動かすため)

    Xcode.png

    何はともあれRunさせる

    Xcode-3.png

    ↑の画像ようにiPhoneのシミュレータでRunボタンをクリックしてみたところ、
    以下のエラーが出ちゃいました。

    スクリーンショット 2012-02-07 16.15.23.png

    確かに、

    Next step is IMPORTANT! Drag the www folder into Xcode 4. You can't just drag the www folder into your app's folder. It needs to be dragged into Xcode 4!! In my case I would drag it and drop it on HiWorld shown below.


    via: Get Started Guide « PhoneGap

    と、どうやらwwwというフォルダがないからプロジェクトに追加してね的な話のようです。
    ここも、過去のPhoneGapでは、wwwフォルダがデフォルトであったりしてたようで、ググるとそっちが出てきてちょっと困ってしまいました。

    そしていろいろぐぐっているとドンピシャな記事が、

    1. XCodeの左ペインのプロジェクトのアイコンを右クリック

    2. Add files to プロジェクト名...を選択

    3. 作成したプロジェクトのフォルダの中にwwwというフォルダがあるので選択

    4. 表示されるダイアログの下の方に「Create folder references for any added folders」というのがあるので選択してAddボタンを押す

    5. XCodeの左ペインの中に青い色でwwwフォルダが表示される

    6. この状態でビルドすればSimulatorでindex.htmlの内容が表示されます


    via: [PhoneGap] PhoneGapでwwwフォルダがない | スタックスリー開発奮闘ブログ

    Xcode-1.png

    これで、wwwフォルダがXCode上に表示され、かつビルドが通るようになりました!
    (なんなんだ、このワンステップは。。。)

    スクリーンショット 2012-02-07 16.23.20.png

    実機で動かす場合

    プロビジョニングファイルの作成

    ぶっちゃけこのステップが一番面倒なんですが、やらないとダメみたいなので、やるしかないですね。
    以下の記事を順番にやっていくと、いつのまにか終わっています。
    ASCII.jp:JavaScriptでiPhoneアプリ開発!NimbleKit入門|古籏一浩のJavaScriptラボ

    そしてiPhoneをつないで、XCodeの「Window→Organizer→DEVICES」にて
    Use for Development
    をクリックすると、これまたいつの間にかiPhoneの認証が終わってる!イエス!

    iPhoneの実機での動作確認

    iPhoneが繋がっている状態なら、XCodeのシミュレータのところに自分のiPhoneの名前が出ているので、それを選択してRunするだけ。
    これで、自分のiPhoneでアプリが動き出す。


    Android版

    必要なものをセットアップ

    Android版はXCodeは使いません。
    なので、eclipseのセットアップをする必要があります。

    eclipseは3.7を使って、Mac版のAll in one eclipseはないので、以下の記事をもとに自力で作ります。
    MacでPleiades All in One Eclipse - Archit!!
    そんなに難しくないので、手順通りに行なってください。
    (All in oneを求めていない方は、eclipse単体でOKです)

    eclipse以外に以下のものが必要になりますが、これはPhoneGapでAndroidアプリを作るための基礎知識(1/3) - @ITこの記事がすごく参考になります。
    セットアップしちゃいましょう!

    1. Android SDK
    2. ADT Plugin
    3. PhoneGap(すでのiPhoneのほうでダウンロードしていますね)

    Android Projectを作成し、PhoneGapに必要なファイルを配置する

    eclipseの「File→New→Other」と選択し、Androidの配下にあるAndroid Projectを選択します。
    プロジェクトが作成されましたら、以下のようにphonegapの必要なファイルをコピーしてください。

    assetsフォルダの下にwwwフォルダを作成
    「phonegap-1.4.1/lib/android/phonegap-1.4.1.js」をコピー
    index.htmlを作成
    プロジェクト直下にlibsフォルダを作成
    「phonegap-1.4.1/lib/android/phonegap-1.4.1.jar」をコピー
    resフォルダの下にxmlフォルダを作成
    「phonegap-1.4.1/lib/android/xml/plugins.xml」をコピー

    あとは、phonegap-1.4.1.jarを右クリックしてBuild PathからAdd to Build Pathを選択します。

    最終的にこんな感じです。
    Java - phonegap_assets_www_index.html - Eclipse - _Users_hisamatsu___dev_workspace.png

    これでベースは整いました。

    Android ProjectをPhoneGap仕様にする

    AndroidManifest.xml

    ここで一点注意ですが、uses-sdk android:minSdkVersionに9と入れていますが、これは2.3.2を意味しています。
    Android SDK Managerでは2.3は2.3.3しかダウンロードできないため、ここで2.3.2を許容しておきます。
    (というかそもそもuses-sdk android:minSdkVersion書かなければいいのかな)

    src/PhonegapActivity.java

    assets/www/index.html

    phonegap-1.4.1.jsファイルはjsというフォルダの中に配置しました。

    何はともあれRunさせる

    プロジェクトを右クリックして「Run As→Android Application」を選択します。
    ちょっと時間がかかります。

    スクリーンショット 2012-02-09 14.10.07.png

    ちょっといいなと思ったのが、一度シミュレータが起動したらそのまま閉じないでおいて、
    index.htmlの修正をしても、もう一度「Run As→Android Application」をするだけです。
    これかなり速いです。
    なので、のっけのシミュレータの起動だけは結構重いですが、その後の修正点の反映は速いかもしれません。

    Androidの実機での動作確認

    Android端末の設定で、「アプリケーション→開発→USBデバックにチェックをつけるだけ。
    これで、プロジェクトを右クリックして「Run As→Android Application」を選択すると、実機側でアプリが起動する。
    簡単!

    ■関連記事
    MacOSX LionにTitanium Mobile(Studioも)をインストールしたときのメモ(2012-02-06時点) - iPhone/Android対応

    ■参考リンク
    以下のリンク先から今回の記事のヒントを大量にいただきました。
    ありがとうございます!
    PhoneGapでAndroidアプリを作るための基礎知識(1/3) - @IT
    PhoneGapを試してみる | Classmethod.dev()
    インストール方法(Android編) | PhoneGap Fan

    PhoneGap 入門ガイド (Smart Mobile Developer)
    アシアル株式会社
    翔泳社
    売り上げランキング: 225899

    MacにGoogle日本語入力を入れている場合、VMwareFusion側のeclipseのCtrl+Shift+Rが効かない場合の対処

    非常に地味な話ですが、
    Mac側にGoogle日本語入力をインストールしていて、かつVMwareFusion側のWIndowsにもGoogle日本語入力入れていて、
    Windows上でeclipseを使う場合、Ctrl+Shift+RがGoogle日本語入力の再変換というキーボードショートカットに奪われてしまう場合の対応になります。
    (この需要あるのかな。。。)

    VMware側のMac OS キーボードショートカットを無効にする

    ちょっとこれしたくなかったのですが、eclipseでCtrl+Shift+Rが使えないのは、ラーメンを前にしてレンゲがないぐらいに大変なことなので、やるよ。僕やるよ。

    スクリーンショット 2012-02-07 13.21.08.png

    VMwareFusionの環境設定→キーボードとマウスで、
    「Mac OS キーボードショートカットを有効にする」のチェックを外します

    Mac側の設定はこれだけ。

    ソフト毎にIMEを切り替える「あいち」をWindowsに入れる

    このソフトを使うと、ソフト毎にどのIMEを使うかを自動で切り替えてくれる。
    つまり、eclipseはMicrosoft IMEだけど、それ以外のソフトではGoogle日本語入力を使う。
    といったことが可能になる。

    ■ダウンロード
    プログラミング研究所 - あいち

    どうやるかは以下の記事が非常に参考になる。
    窓の杜 - 【REVIEW】アプリケーションごとに利用するIMEを自動で切り替える「あいち」

    僕は、対象のソフトがアクティブになった場合に出る通知機能は無効かしました。

    Windows 7 x64.png


    これよりももっといい方法あるとは思うんですが、いまいちわからなかった。
    一個デメリットは、Windows側でCmd+Tabすると、エアロが起動してしまうこと。
    Mac側のアプリ切り替えが動いて欲しいが、ショートカットを無効化してしまっているので、ここはしょうがないですね。

    まとめ

    1. VMwareFusionのMac OS キーボードショートカットを無効にする
    2. あいちをWindowsにインストールする
    3. eclipseの場合にMicrosoft IMEにするようにする

    こんな感じですね。

    VMware Fusion 4 プロモーション期間限定優待版
    アクト・ツー (2011-10-14)
    売り上げランキング: 187

    MacOSX LionにTitanium Mobile(Studioも)をインストールしたときのメモ(2012-02-06時点) - iPhone/Android対応

    必要にせまられて、Titanium MobilePhoneGapの調査が必要になったので、いろいろとメモを残しておきます。

    今回Titanium Mobileの解説になります。
    一応Titanium Mobileを入れた環境を以下に列挙しとく。

    MacOS X
    Lion
    Java
    1.6.0_29
    Titanium SDK
    1.8.1
    Titanium Studio
    1.0.8

    ちなみに、LionからデフォルトでJavaが入らないので、自分でSDKをインストールする必要があります。

    Titanium Mobileのダウンロード(with Titanium Studio)

    まずは、Titanium Studioをダウンロードします。
    こちらをダウンロードすると、自動的にTitanium Mobileもダウンロードされます。

    いろいろTitaniumのことでググるとTitanium Developerのことが検索されますが、今はもうTitanium Studioに統合されているようです。

    Sign Up for an Appcelerator Developer Account
    にアクセスし必要な情報を入力しサインインする。

    あとは、Resources画面からOS X版をダウンロードする。

    Titanium Studioを起動してみる

    eclipseベースなので比較的見慣れたUIですが、デフォルトで背景が黒いが個人的には好き。
    起動すると、しばらく右下のあたりでゴニョゴニョアップデートに関する動作があるので、少し待ちましょう。
    すると、Titanium Studioのアップデートを促されるのでやっちゃいます。やっちゃいましょう!

    何はともあれTitanium Mobile Projectを新規作成してみる

    メニューの「File」→「New」→「Titanium Mobile Project」を選びます。

    そして以下のように必要な項目を入力していくんですが、ここで一つ問題が。
    Androidのチェックボックスは、そもそもAndroidのSDKが入っていないとチェックができません。
    おそらくiPhoneも同様だと思います。(すでにXCodeを入れていたので未確認)
    iPhoneSDKに関しては目指せ!iPhoneアプリ開発エキスパート:第2回 iPhone SDKの入手と設定|gihyo.jp ... 技術評論社の記事をご覧ください。

    New Titanium Mobile Project.png

    なので、一旦プロジェクトの新規作成は置いておいて、AndroidのSDKをインストールします。

    AndroidSDKをダウンロードする+そしてSDKをインストールする

    Android SDK | Android Developers
    からandroid-sdk_r16-macosx.zipを選びました。

    解凍後、/android-sdk-macosx/tools/andoroidをダブルクリックしてAndroid SDK Managerを起動します。

    ちなみにですが、この時点、つまりAndroidSDKはダウンロードしたけど、まだどのバージョンのSDKもインストールしていない状態で、Titanium Studioの設定で、/android-sdk-macosx/の場所を指定してもSDK自体がインストールされていないので以下のようなエラーがでます。

    SDK at the given path has the following error: E...ion: No "android-8" or "android-2.2" in the Android SDK

    (のちのちさらにこのメッセージの意味を知ることになるとは・・・)

    話をAndroid SDK Managerに戻します。
    今回はスマートフォンアプリの開発に使うので、2.3をインストールします。
    結構時間がかかりますが、気長に待ちましょう!
    あと僕はExtrasというところにある「Google〜〜」というのもほとんどインストールしておきました。

    再度Titanium Mobile Projectを新規作成してみる

    これで、ようやくiPhoneAndroidにチェックを入れた状態でプロジェクトを作成することができます。

    AndroidSDKのパスを通す(がしかし)

    「Preferences→Aptana Studio→Titanium」でAndroidのパス「/android-sdk-macosx/」を指定します。
    このディレクトリは人によっては違うと思いますので、ご自分のパスを指定してください。

    Preferences.png

    ただし、これだけでは実はうまくいかない。

    SDK at the given path has the following error: E...ion: No "android-8" or "android-2.2" in the Android SDK

    相変わらずこのエラーが取れないのだ。
    まぁ、よく読むとandroidの2.2が必要だと言っているようです。
    とくに2.2が必要ではないんですが、このエラーを取り除くには2.2を入れるしかないので、もう一度Android SDK Managerからインストールしてください。
    ちなみにこの2.2というのは、最新のTitanium Studioのバージョン(2012-02-06)の場合なので、2.1を要求される場合もあるようです。

    iPhone、AndroidのシミュレータでRunしてみる

    やっとここまできました!
    では実際にシミュレータで動かしてみましょう。

    「Project Explorer」ペインの自分で作ったプロジェクトを右クリック→Run AsからiPhone Simulator選びます。

    スクリーンショット 2012-02-06 17.41.38.png

    続きまして、同じくRun AsからAndroid Emulatorを選びます。
    (iPhoneとは比べ物にならないくらい時間がかかります。本気です。)

    スクリーンショット 2012-02-06 17.52.50.png

    iPhoneではフッターにタブが表示されていますが、Androidのほうはヘッダーにタグが表示されています。
    (こうゆうもんなのかな?いずれわかるときが来るであろう)

    いろいろサンプルが詰まっているKitchenSinkで遊んでみる

    ↑で試したのはたんなるタブがあるだけのサンプルですが、実際にどんなUIが出来上がるのかをいろいろ試せるKitchenSinkを使ってみましょう!
    なんとありがたいことに、Titanium Studioから直接このサンプルをダウンロードできます。

    Web - test_Resources_app.js - Titanium Studio - _Users_hisamatsu___dev_TitaniumStudioWorkspace.png

    あとは、KitchenSinkプロジェクトをRunさせるだけです。

    スクリーンショット 2012-02-06 18.01.51.png

    ■KitchenSinkのgithub
    appcelerator/KitchenSink - GitHub

    KitchenSinkでだいたいのエッセンスが詰まっているので、あとはこれを応用する感じになるのかなーと思っています。
    (ほんといっぱいサンプルあるので、助かります)

    スクリーンショット 2012-02-06 18.53.37.png

    そして、実はこのプロジェクトをAndroidのEmulatorで実行すると以下のエラーが出ます。

    [ERROR] Failed installing com.appcelerator.titanium: pkg: /data/local/tmp/app.apk

    このエラーに悩まされて、断念された方も多々いるようですが、

    結論として、Run Configuration で Android 2.2 じゃなくて、Google APIs Android 2.2 を使う。


    via: 静電気日記@vg4.net : Titanium Studio for Windows 1.7.2で KitchenSink 起動させるプロジェクト。 - livedoor Blog(ブログ)

    これで解決しました。

    とにかくTitanium Mobileでググると古い情報が上位に来てしまうので、今後この記事も同じように古くなってしまうとは思いますが、どなたかの手助けになれば幸いです。

    また、こちらの記事のように、
    初心者でも2週間でiPhoneアプリが作れちゃうTitanium Mobileがすごい件 | 株式会社インフィニットループ技術ブログ
    CoffeeScriptで組んでみるのも面白いかもしれません。

    iPhoneの実機での動作確認

    そっこうでエラーになって入らない。

    [INFO] One moment, building ...
    Traceback (most recent call last):
    File "/Users/XXXX/Library/Application Support/Titanium/mobilesdk/osx/1.8.1/iphone/builder.py", line 1537, in
    main(sys.argv)
    File "/Users/XXXX/Library/Application Support/Titanium/mobilesdk/osx/1.8.1/iphone/builder.py", line 705, in main
    dist_name = dequote(args[7].decode("utf-8"))
    File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/encodings/utf_8.py", line 16, in decode
    return codecs.utf_8_decode(input, errors, True)
    UnicodeDecodeError: 'utf8' codec can't decode byte 0x97 in position 0: invalid start byte

    TitaniumでiPhoneへの実機転送時にはまった件のまとめ - Titanium/Androidアプリ開発メモに書かれているように、

    1. プロビジョニングプロファイルを指定したパスに日本語が入っている
    2. プロビジョニングプロファイルを作るために必要な証明書に日本語が含まれている

    僕はこの2個目のほうでハマった。
    そもそもAppleアカウントのfirstNamelastNameが日本語なのがまずかった。
    しかも、これはこちら側では変えられない項目なので、Developer Centerにメール(英語)で依頼する必要がある。(面倒!)

    そしてメールしてみた結果、

    既に開発チームの一員でいらっしゃるので、
    氏名修正の手続きは長く、手間がかかる可能性がございます。
    なお、修正させて頂けることは保証できません。

    ということなので、諦めてAppleIDの再取得をして、Apple Developer Programに追加してもらいました。
    そして再度同じことを実施して、プロビジョニングプロファイルを作成して同期してみたところ、iTunesが起動してAPPの同期でうまいことiPhoneにアプリが入りました!

    メモ:
    Titanium StudioでiPhone実機転送をする方法 | zaru blogを読むと、あまりiTunesのアップデートをおろそかにすると、エラーが出るケースがあるようです。

    Androidの実機での動作確認

    こっちもそっこうでエラーになって入らない。

    [ERROR] Failed installing com.hisasann: pkg: /data/local/tmp/app.apk.
    INSTALL_PARSE_FAILED_INCONSISTENT_CERTIFICATES

    いろいろ試してみたんですが、結局Application IDのところにドットを2つ使うようなIDにしたらうまくいきました。
    「com.hisasann.test」
    のように、
    「com.hisasann」
    は、なぜかダメでした。
    ただ、これは翌日になるとcom.hisasannでもうまいこと実機に転送されたので、いったいなんだったのか。。。

    とりあえず今後はドットを2つ使うようにします。
    Titanium Studioで実機に転送できない at nought

    こちらでもドットについて言及されていました。

    App Id:com.example.ti.blank

    + ドメイン名を逆さ+適当

    + 必ずドット"."を含むこと(でないとandroidの時動かないよ)


    via: Titanium Mobileセミナーに行ってきたのでそのメモ - I'm hungry

    さらにちょっとややこしいのが、実機にアプリを転送しても勝手に起動してくれません。

    アプリは勝手に立ち上がらないので、コンソールに「Application installed. Launch from drawer on Home Screen」と出たら、自分でアプリケーションメニューを開いて、インストールされているアプリを起動しなくては行けません。


    via: Mobile Dev. (Android + Java) » Titanium Studioで作成したプロジェクトを実機にインストールする

    やっとこの感覚になれてきましたが、はじめは分からないものですね。


    ■参考リンク
    Titanium StudioでiPhoneアプリを作ろう その1 - n-channelの日記
    開発環境をつくるべし! - Titanium StudioではじめるAndroidアプリ開発
    yoo-s.com
    今後はTitanium Studioで開発を。 | 備忘録的なブログ
    Titanium Studio をアップデートしたら Android SDK を認識しなくなった件 - モトクロスとプログラムと粉砕骨折と
    Sawalog » Titanium StudioでAndroid SDKを設定する方法
    Titaniumで作るAndroidアプリ開発(Titaniumインストール~サンプルアプリ"Kitchen Sink"起動) - jitsu102の日記
    Titanium Mobile 用に Android SDK をインストールする | Bowz::Notebook
    Titanium Mobile(with Titanium Studio)のサインアップとダウンロードの方法が変わっているようです。 - JP::HSJ::Junknews::HatenaSide

    番外編 - Android開発を速くするfastdevを使ってみる

    Androidのビルドはとにかく重いです。
    iPhoneと比べると5倍くらい時間が掛かるような気がします。

    そんなAndroid開発ですが、Titanium Mobileの1.7.0からfastdevという機能がついたようです。
    では、それを使って何が速くなったのかを体感してみたいと思います。
    まずは、「.bash_profile」に以下のエイリアスを追加します。

    alias titanium="~/Library/Application\ Support/Titanium/mobilesdk/osx/1.8.1/titanium.py"

    そして、新規作成したプロジェクトまでターミナルで移動して、以下を打ちます。

    $ titanium fastdev start &
    [1] 4194
    $ Fastdev server already running for com.hisasann.test

    なんか、すでに動いているよって言われた。。。
    1.8からは自動でfastdevが動いているのかしら。

    なので、適当にapp.jsのコードをいじってみて、以下を打ってみました。

    $ titanium fastdev restart-app
    Restarted app com.hisasann.test.

    するとシミュレータを再起動せずにコードの修正ができました!
    このディレクトリに毎回移動してコマンドを打つのがちょっと面倒(ボタンがあればいいのに)ですが、
    これを使わない手はありません。

    Titanium mobile Fastdevでアプリの変更をAndroidに即反映|WEBデザイン Tips

    追記:2012-02-16 - Adobe Unit Types.osaxエラー

    /Library/ScriptingAdditions/Adobe Unit Types.osax

    このような一体何に使っているか分からないスクリプトファイル?でエラーがでた場合は、
    Error about unit type conversion occurs when running an AppleScript in Photoshop (Mac OS X 10.6)
    をもとにファイルを差し替えるとエラーが出なくなる。

    このワンステップも個人的には結構ハマりました。

    [via]
    Titanium StudioでiPhone実機転送をする方法 | zaru blog

    Titanium Mobileで開発するiPhone/Androidアプリ (Smart Mobile Developer)
    北尾 雅人
    翔泳社
    売り上げランキング: 11403

    ブログをfacebookのOGP(Open Graph Protocol)に対応させる

    WordpressMTについてですが、以下にメモしとく。

    そもそものOGPについてですが、ご存知のとおりいいね!ボタンを押されたときに、facebook側に対していろいろとサイトの情報を教えてあげるためのmetaタグ情報ですが、どうやらこれをちゃんとやっておかないと自分の友達のフィードに流れていかないよう。
    なので、これは積極的にBlogに導入するほうが無難かもしれませんね。

    なぜなら『OGP』を設定しないで『いいね』ボタンをクリックすると、友人のニュースフィールドにその情報が表示されないからです。これではせっかく『いいね』ボタンをクリックされても他の人が見ることがないので広がりも少なくなってしまいます。


    via: facebook いいねボタンの仕様変更?OGPの設定についてまとめました( localeプロパティについて) | HTML5でサイトをつくろう

    そんなに面倒なものでもないのでやっちゃいましょう!

    OGPのmetaタグを追加する

    以下はWordpress仕様で書いております。

    AppIdの取得は以下の記事が参考になります。
    facebook いいねボタンの仕様変更?OGPの設定についてまとめました( localeプロパティについて) | HTML5でサイトをつくろう

    OGPのmetaタグを追加する(MTに依存する箇所)

    htmlタグに以下2つのxmlns名前空間を追加します

    いいね!ボタンを配置する(HTML5バージョン)

    今までiframe版を使っていたんですが、ここ最近HTML5版に切り替えたところすこぶる速くなりました。
    HTML5版も結果的にiframeを作りますが、画面のロード後に実行されるのでレンダリングが邪魔されません。

    body開始タグすぐに以下を

    いいね!ボタンを設置したい場所に以下を(Wordpress版)

    いいね!ボタンを設置したい場所に以下を(MT版)

    この一手間でほんの少しでもPVを〜!

    ■関連リンク
    フェイスブック、ミクシィ、グリーで使われている OGP (Open Graph Protocol) とは何か - IT戦記

    Facebook Perfect Guide Book
    Facebook Perfect Guide Book
    posted with amazlet at 12.02.06
    森嶋 良子 鈴木 麻里子 田口 和裕
    ソーテック社
    売り上げランキング: 448

    Vimをちゃんと使い始めてみる - MacそしてWindows

    スクリーンショット(2012-02-20 1.02.16).png

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

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

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

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

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

    カラースキーマの保存場所

    $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ログ

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


    追記:2012年 7月24日 火曜日 11時56分08秒 JST

    プラグインの管理はvundleを使っております。


    便利機能

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

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

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

    を.vimrcに追記すればOK!

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

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

    • Ctrl + c
    • Ctrl + [

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


    僕のvimの設定たち

    .vimrc

    dotfile/.vimrc at master · hisasann/dotfile · GitHub

    .gvimrc

    dotfile/.gvimrc at master · hisasann/dotfile · GitHub

    dotfile

    hisasann/dotfile · GitHub


    Windows環境でVimを使う

    本家の
    Vundle for Windows · gmarik/vundle Wiki
    に書かれている内容をやっていったのでメモ。

    gitをインストールする

    もともと「msysGit」をインストールしていたんですが、インストールされているディレクトリがvundle側が想定しているところと違ったので、
    「Git-1.7.11-preview20120710.exe」をインストールした。

    And copy it to C:\Program Files\Git\cmd\curl.cmd, assuming msysgit was installed to c:\Program Files\Git

    to verify all good, run:

    そのときに、「Run Git from the Windows Command Promt」にチェックを付けていつでもgitコマンドを使えるようにしといた。

    インストールが完了したらgitの確認。

    $ git --version
    git version 1.7.11.msysgit.1

    curlの準備

    「C:\Program Files\Git\cmd\curl.cmd」に以下の内容のcmdファイルを置く。
    ちなみにsjisで保存しないとうまく動かなかったです。

    @rem Do not use "echo off" to not affect any child calls.
    @setlocal

    @rem Get the abolute path to the parent directory, which is assumed to be the
    @rem Git installation root.
    @for /F "delims=" %%I in ("%~dp0..") do @set git_install_root=%%~fI
    @set PATH=%git_install_root%\bin;%git_install_root%\mingw\bin;%PATH%

    @if not exist "%HOME%" @set HOME=%HOMEDRIVE%%HOMEPATH%
    @if not exist "%HOME%" @set HOME=%USERPROFILE%

    @curl.exe %*

    curlコマンドの確認。

    $ curl --version
    curl 7.26.0 (i686-pc-mingw32) libcurl/7.26.0 OpenSSL/0.9.8x zlib/1.2.7
    Protocols: dict file ftp ftps gopher http https imap imaps ldap pop3 pop3s rtsp
    smtp smtps telnet tftp
    Features: GSS-Negotiate Largefile NTLM SSL SSPI libz

    vundleを使えるようにする

    vundleをcloneしてくる。

    $ cd %USERPROFILE%
    $ git clone http://github.com/gmarik/vundle.git .vim/bundle/vundle

    あとは_vimrcにBundleを記載して、:BundleInstallをしまくるだけなんですが、
    WindowsでVundleを使うときにはまったこと - まだ決めてない
    そろそろしっかりvimを使う。github+vundleを利用したWindowsとの同期。 - holyppの日記
    こちらに書かれているように、

    call vundle#rc('~/vimfiles/bundle')

    こっちを見に行くようにすると「E117: 未知の関数です: vundle#rc」とエラーがでてうまく動きませんでした。

    filetype off
    filetype plugin indent off

    set rtp+=~/.vim/bundle/vundle/
    call vundle#rc()

    Bundle 'gmarik/vundle'

    なので、普通に上記のコードのままいったらうまくいった。
    バージョンアップなどで使い勝手が変わったのだろうか。

    最後に必要なBundleたちを記述して、
    「:BundleInstall」
    でOK!

    困ったこと

    _vimrcに書いてて、Windowsのほうだとダメだったのでif文にした。

    " encoding
    if has("win32") || has("win64")
    " sjisはWindows用
    set encoding=sjis
    else
    set encoding=utf-8
    endif

    " doc
    " Windowsだとこのdocディレクトリがないため
    if has("win32") || has("win64")
    " helptags ~/.vim/doc
    else
    helptags ~/.vim/doc
    endif


    今使っているBundleたち

    なんだかんだでこうなった。(2012年 7月24日 火曜日 11時44分44秒 JST 現在)

    Bundle 'gmarik/vundle'
    Bundle 'YankRing.vim'
    Bundle 'neocomplcache'
    Bundle 'h1mesuke/vim-alignta'
    Bundle 'ZenCoding.vim'
    Bundle 'MarcWeber/vim-addon-mw-utils'
    Bundle 'tomtom/tlib_vim'
    Bundle 'snipmate-snippets'
    Bundle 'garbas/vim-snipmate'
    Bundle 'othree/html5.vim'
    Bundle 'cocoa.vim'
    Bundle 'thinca/vim-quickrun'
    Bundle 'tpope/vim-markdown'
    Bundle 'open-browser.vim'
    Bundle 'scrooloose/nerdtree'
    Bundle 'tpope/vim-surround'
    Bundle 'JavaScript-syntax'
    Bundle 'pangloss/vim-javascript'
    Bundle 'majutsushi/tagbar'
    Bundle 'Shougo/unite.vim'
    Bundle 'Lokaltog/vim-powerline'
    Bundle 'c9s/cascading.vim'

    もう、unite.vim最高!

    ■関連リンク
    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)するときに気をつけたいこと