実践入門 Ember.js の第4回が公開されました

第4回 ユーザのインタラクション(Controller, Component):実践入門 Ember.js|gihyo.jp … 技術評論社

今回で Ember.js の連載は折り返し地点となります。 ここまで Computed Property の説明が出てこなかったのが驚きですね。*1

次回からはもうちょっと手の込んだアプリケーションを取り上げていく予定です。 読んでくれている方々にとって、もっと楽しめるものになりますように。

*1:一昔前の紹介記事だと、この Computed Property を一番最初に説明するのが通例でした

実践入門 Ember.js の第2回が公開されてました

第2回 URLと画面表示(RoutingとTemplates):実践入門 Ember.js|gihyo.jp … 技術評論社

がんばります。

Crevo 開発チームの勉強会で gem の探し方についてお話しました

ここ 1年半くらい Crevo の開発チームにお世話になっているのですが、先月から週イチで勉強会をすることになりました。 ここでは持ち回りで何かしらの発表をすることになっていて、今日はぼくが当番の日でした。

ということで、自分が gem を探す時のやりかたをお話させてもらいました。

こう、しれっと自分のプロダクト紹介するのはじわじわきて楽しいですね。

ember-rails のメンテナになりました

Ember.js を Rails から使うための gem である ember-rails のコミット権をいただきました。


emberjs/ember-rails · GitHub

Ember RailsEmber.js Organization に属しているので、
ぼくの Github のプロフィールページ でも Ember.js アピールができるようになりました。

Ember.js を好きなかたもこれから好きになるかもしれない方も、
どうぞよろしくお願いいたします。

Ember.js の連載を始めました

gihyo.jp で Ember.js の連載をさせてもらうことになりました。
実践入門 Ember.js:連載|gihyo.jp … 技術評論社

ぼくが普段 Ember.js を使った開発で感じている楽しさ・快適さをお伝えできるといいなと思っています。

そんな第1回の記事はこちらです。

連載期間はおよそ半年を予定しています。
短い期間ではありますが、どうぞお付き合いくださいませ。

GitHub のアスキーアートで遊んでみた

最近、Ember.js アピールが足りてないと感じたので、GitHub 上でもう少しアピールしてみることにしました。

Generated by https://github.com/tricknotes/we-love-ember

Ember.js はレガシー IE でも動くようになっています、を対応しましたという話

この記事は Ember.js Advent Calendar の1日目です。

やはり Ember.js は大人気のようで、 Advent Calendar もあとたった 22 枠しか空きがありません。(12/1現在)
すこしでも Ember.js に興味がある方は急いで登録されることをオススメします!

この記事では私が Ember.js に送ったのレガシー IE 対応のパッチをご紹介しつつ、IE での JavaScript の罠とその対応を紹介します。
今現在 IE と向き合っている方や、これから IE と向き合うことになる方のご参考になれば幸いです。

ちなみに、 Ember.js は 1.0.0 の時点で IE 6 ですべてのテストケースに通過しており、1.2.2 (現在の最新の安定版) でも IE6 上で動作します。

ここで、レガシーIE が何か、というのを定義しておきましょう。 本記事ではレガシーIE とは IE 6, 7, 8を指すことにします。
そして今回はレガシー IE についてのみ言及しているので、以降は単に「IE」と呼ぶことにします。

IE での罠たち

IE の JavaScript には多くの罠が存在します。
それもそのはず、 IE 9 未満は ECMA-262 ではなく JScript という JavaScript っぽい独自の言語だからです。

なので、まずは現在多くのプラットフォームで動作することが期待されている ECMA-262 3rd edition と互換性を目指すことで IE 対応を進めていきたいと思います。

Array にはメソッドが足りない

ECMA-262 3rd edition で定義されている Array のメソッドの中で、 JScript では定義されていないメソッドがいくつか存在します。

  • Array.prototype.forEach
  • Array.prototype.map
  • Array.prototype.indexOf

そこで、 Ember.js にはこれらの足りないメソッドのために、互換性のある関数群が用意されています。

  • Ember.ArrayPolyfills.forEach
  • Ember.ArrayPolyfills.map
  • Ember.ArrayPolyfills.indexOf

この関数群には、該当する Array にメソッドがすればそのメソッドが、なければ独自に定義した互換関数が格納されています。

ということで、この点についての IE 対応は比較的簡単です。 forEachmap が使われている箇所を、すべて互換関数に置き換えてしまえば対応完了です。

host object にはメソッドが足りない

ホストで提供されている Function には本来 Function オブジェクトが持っているはずのメソッドである toStringapply が定義されていません。

信じられないことに、次のコードは IE では実行時例外となります。

setTimeout.toString();
//=> throw 'Object doesn't support this property or method'

toString に関しては、

String(setTimeout);
//=> 'function() { [native code] }'

で回避できます。

ただし apply については一工夫必要です。

稀に、setTimeout を一時的にオーバーライドして引数をチェックした上で本来の setTimeout に渡したい、とったようなケースがあり、その際には apply をなんとかして使う必要があります。
私は Function.prototype.applysetTimeout に apply することで対応することにしました。

var apply = Function.prototype.apply;
apply.apply(setTimeout, [this, arguments]);

Object.prototype のプロパティと同名のプロパティが for in で列挙されない

通常 for ~ in ループでは、オブジェクト自身が持っているプロパティを列挙することができます。 しかし IE では、Object.prototype で定義されているプロパティと同じ名前のプロパティについては列挙されません。

var object = {
  toString: function() { return 'hi' }
};

for (var key in object) {
  // 一般的な JavaScript とは違い、toString が列挙されない。
}

この対応についてはかなり悩んだ結果、事前に Object.prototype のプロパティ名の配列を用意しておき、ひとつひとつプロパティをチェックするようにしました。

var keys = [
  'constructor',
  'hasOwnProperty',
  'isPrototypeOf',
  'propertyIsEnumerable',
  'valueOf',
  'toLocaleString',
  'toString'
];

for (var i = 0, length = keys.length; i < length; i++) {
  if (object.hasOwnProperty(key)) {
    // ここでは toString が取得できる
  }
}

暗黙の global 変数と window のプロパティは別

IE では 「global 変数 = window のプラパティ」というわけではありません。

greet = 'hi';

window.greet; //=> 'hi'
greet; //=> 'hi'

window.greet = 'bye';

window.greet; //=> 'bye'
greet; //=> 'hi' // ここで一般的なブラウザは 'bye' が変える

globa 変数を使わなければ問題ないように見えますが、もとから存在する global 変数を一時的にスタブしたいといった場合には致命的な挙動となります。 なので、そういったケースであれば、常に window 付きで変数にアクセスするというのが有効です。

その他

他にも、Object.create が不完全な状態で実装されていたり<a> の href に必ずホスト名が含まれたり<input type=checkbox>は focus して blur しないと change イベントが発火しなかったりといった DOM 由来の奇妙な動作がいくつかあるんですが、今回は詳しい説明は割愛します。

感想

苦行とされるIE対応も、やってみると意外な発見がありました。

  • 納期も制約もない IE 対応は意外と楽しい
  • 得られる知見が多く、マルチプラットフォームで動くコードを維持する大変さを体感できる(ただし未来へつながる知見はない)

ちなみに、わたしがなぜ Ember.js の IE 対応を行なっているかというと、もちろん Ember.js 自体の価値になるというのもあるんですが、 一番の理由は過去に経験した IE 対応の案件で大変苦い思いをしたからです。
当時 IE をあまく見すぎていたために、時間・体力・精神力の大部分を持って行かれてしまいました。
案件が始まる前からちゃんと IE と向き合っていられれば、そして当時 IE に対応した Ember.js があれば、何かが違っていたかもしれません。

そこで、「過去の自分を救いに行く作業」を経験された hmsk センパイを見習うことにしたのです。

まとめ

今回ご紹介したのは、実は JavaScript の IE 対応のほんの一部の Tips です。
実際に web サイト/アプリを IE 対応させようとした場合には、 JavaScript 以外にも DOM や CSS も対応させる必要がありますし、 さらにそれを統合した状態で期待通りに動くよう調整を行なう必要があります。

というわけで、IE と向き合っているみなさまにとって、本記事が少しでも手助けになれば幸いです。

では、引き続き Ember.js Advent Calendar をお楽しみくださいませ :-)