カテゴリー別アーカイブ: 覚書

Fire.appをビルドして使う


Fire.appというHamlとかSassをコンパイルするディレクトリを注視してファイルが更新されたら勝手にコンパイルしてくれるアプリケーションがあります。(似たようなアプリにCodeKitがありますが、Mac Lion以上専用です。)

http://fireapp.handlino.com/

Githubでソースが公開されているのでビルドして使うことができます。

続きを読む Fire.appをビルドして使う

wmodeのもたらす不具合


Flashで背景を透過させるときにHTMLのSWFObject部分にwmode=”transparent”;と書くこともあると思いますが、これが結構不具合(仕様?)が多く、安易に使えません。

さっと確認した感じではwmodeをきちんと設定しないと、以下のような不具合が出たり出なかったりします。(FlashPlayerのバージョンによって変わるものもあります。)

  • ブラウザによってポップアップブロックに引っかかったり引っかからなかったりする
  • 文字入力がブラウザによってインライン入力できたりできなかったりする
  • ブラウザによって日本語入力ができたりできなかったりする
  • CSSのz-indexがwmode=windowでは無視される(Flashが最前面に表示される)

などなど

このできたりできなかったりする、というのが曲者です。ブラウザによってFlashが違う動作をするときはまずwmodeを疑うと良い気がします。
Flashは全部のブラウザで動くんだぜーとかやってると返り討ちにあいます。wmodeの設定によってはちゃんと動くようになる場合がありますが、こいつがやっかいなのは、ブラウザごとに動作を分ける必要があって、

  • wmode=transparent
  • wmode=window
  • wmode=opaque
  • wmode=direct
  • wmode=gpu

のどれが適切かはFlashとブラウザとOSによって異なるので、ブラウザごとに適切なwmodeを選んでいく必要がある場合があるということです。

以前にWindows7のChromeで日本語入力ができない、というのに悩まされました。これは一時wmodeを設定しないか、windowに設定すれば動くものの、それ以外だと動かない、という状況だったんですが、あとになって、逆にopaqueかtransparentにすると動くという風になったりでもうちんぷんかんぷんです。(検証が不十分だったのかもしれないですけれど。)

さきほど確認したところではWindowsで以下の不具合はまだあるようでした。

  • Windows + Firefoxだとopaque/transparentで日本語インライン入力ができない(Win7 + Firefox + FlashPlayer11.3で確認)
  • Windows + Operaだとopaque/transparentで日本語が入力できない(WinXP7 + Opera12 + FlashPlayer11.3で確認)

Flashのバージョンによりけりの可能性もあるので、transparent/opaqueを使う場合はいつもより念入りにチェックする必要がありますね。特に文字入力がある場合は。

Macではインライン入力ができない…というのがありますが、もともとどのブラウザでも、どのwmodeでもできないのであんまり関係ないですね。(どこかで、仕様なのでインライン入力できるようにはならない、と言われていた気がする。)

ちなみにwmode=window / direct / gpuはそれぞれ動作に違いはなさそうでした。検証が不十分なので、実際に使われる場合はFlashといえどブラウザのチェックは必要かと思います。特に日本語入力は一切できないものもあるので。

カスタムクラスのプロパティをfor..inで出力


wonderflに昔、こんな感じでforkしてみたものがあったんですが、理由が分からなかった部分を調べたまとめ。

通常、for..inをした場合、Objectとして作成したものは出力できますが、カスタムクラスのプロパティだとそれができません。

//Objectだとできる
for(var i:uint = 0; i < LOOP; i++){
    var id:String = 'id' + String(i+1);
    var name:String = 'name' + String(i+1);
    var obj:Object = new Object();
    obj.id = id;
    obj.name = name;
    _listObject.push(obj);
}
for(i = 0; i < LOOP; i++){
    var o:Object = _listObject[i];
    for(var prop:String in o){
        trace(o[prop]);//できる
    }
}

//カスタムクラスのプロパティはでない
for(var j:uint = 0; j < LOOP; j++){
    var id:String = 'id' + String(j+1);
    var name:String = 'name' + String(j+1);
    var obj:TestObject = new TestObject();
    //TestObjectはidとnameをpublic変数に持つものとする
    obj.id = id;
    obj.name = name;
    _listObject.push(obj);
}
for(j = 0; j < LOOP; j++){
    var o:Object = _listObject[j];
    for(var prop:String in o){
        trace(o[prop]);//何も出力されない
    }
}

何故できないのか、と考えてみたんですが、for..inする場合には、そのクラスでpropertyIsEnumerable(プロパティ名)というメソッドを使った時にtrueが帰ってくる必要がありそうです。

ただ、こちらのメソッド、Objectに定義されているものをoverrideすることはできないので、書く必要があるんですが、全てtrueが帰るようにしてもうまく動作しません。prototypeを拡張しても効果無しです。

しかし、たまたまいじっていたらpropertyIsEnumerableがtrueになった、というかfor..inで出力されるようになりました。そのクラスのprototypeにプロパティと同名の変数を定義した場合です。

Object型の場合は値を代入した瞬間に同様の処理をされているのか?とも思いますが、理由は良く分かりません。

サンプルはこちら。

どうせデバッグ用にしか使わないだろうので、処理速度がどう変わるのか、などは検証していません。これが自動化できれば凄く便利な気もします。ただそもそもプロパティの列挙をするためにプロパティを全て知らなければいけないという面倒さがありますし、整形して出力したければ、toStringを実装する時にそのように書いた方が楽な気がしますし。

というわけで、調べたことのメモでした。