読み書きプログラミング ブログ

2015-09-11

はてなブログに引っ越しました

はてなブログがCoffeeScriptシンタックスハイライトをサポートしているので、そちらに引っ越しました。

http://nextliteracy.hatenablog.com/

2015-08-01

[] ファイルの文字コードの自動判別

AtomシフトJISのファイルを扱うことがあって、自動判別忘れに苦しみました。

ググるとちゃんと解決してくれている人がいました。

ATOM でファイルを開いたら自動文字コード判定を行う

ところが、これだと手動でファイルを開いた時にはOKですが、フォルダ指定してatomを起動した時に、以前に開いていたファイルに関しては自動判別してくれません。

Atom discussionで聞いてみたらあっさり解決。onDidOpenの代わりにobserveTextEditorsを使えばいいとのこと。

fs = require('fs')

atom.workspace.observeTextEditors (editor) ->
  try
    filePath = editor.getPath()
  catch error
    return
  return unless fs.existsSync(filePath)

  jschardet = require 'jschardet'
  iconv = require 'iconv-lite'
  fs.readFile filePath, (error, buffer) =>
    return if error?
    {encoding} = jschardet.detect(buffer) ? {}
    encoding = 'utf8' if encoding is 'ascii' or encoding is 'windows-1252'
    return unless iconv.encodingExists(encoding)

    encoding = encoding.toLowerCase().replace(/[^0-9a-z]|:\d{4}$/g, '')
    editor.setEncoding(encoding)
  return

エンコードの自動判別でwindows-1252にフォールバックする場合もあるので、その場合もUTF-8にするようにしました。

とても快適です。

コードがencoding-selector packageのコード丸写しなのは、encoding-selectorのメソッドが公開されていないからですが、元々encoding-selectorが自動判別機能を持つことが筋が悪い。text-bufferが持つべきなのでissueを上げていますが、果たして取り上げてもらえるかどうか。

https://github.com/atom/text-buffer/issues/86

[] レスポンシブなページネーション

Bootstrapのページネーションボタン、長すぎると困ります。

で、レスポンシブにしてくれるjQueryプラグインがありました。

http://auxiliary.github.io/rpage/

素晴らしい。

ただページネーションの隣にインライン要素があると動かなかったり、コードが少しあれだったりしたので、CoffeeScriptで書き直してみました。

https://github.com/y-ich/rpage

検討時間的に一番頑張ったのは、ページネーションボタンの折り返しをなくして、widthの計算をボタンひとつひとつの和ではなくてページネーションそのもののwidthとしたところ。CSSの勉強になりました。

でもこれ、テストにある通りの複数のページネーションのresize時とても遅いんですよねぇ。どこかに変なタイマー入っているのかと思うほど遅い。DOMの計算の重さを実感しました。

2015-06-23

[] Iron Routerのフックの覚書

  • Iron Routerには以下の5つのフックが定義できるようになっている。
  • onRun
  • onRerun
  • onBeforeAction
  • onAfterAction
  • onStop

その他に呼び出しのタイミングを考慮する上で、

  • subscriptions
  • waitOn

オプションがある。

ここまでで1つ覚えておくことは、onRun, onStop以外はリアクティブに再計算されるということ。

次に、呼び出される順序は、通常(waitOnで返すハンドルのready()が一旦はfalseを返すような場合)

  1. subscriptions #1
  2. waitOn #1
  3. onRun #1
  4. onAfterAction #1
  5. subscriptions #2
  6. waitOn #2
  7. onRerun #1
  8. onBeforeAction #1
  9. action(というよりpage rendering) #1
  10. onAfterAction #2
  11. onStop #1

これは解説が必要で、

  1. まずsubscriptions/waitOnがコールされる
  2. onRunがコールされる
  3. waitOnの戻り値のready()がfalseなら、onBeforeActionとactionが見送られて、onAfterActionがコールされる。
  4. Iron Router 1.0の仕様ではどうも、waitOnの戻り値のready()がtrueになるとリアクティブな再計算とみなされるようで、subscriptions/waitOnがコールされる(注1)
  5. 再計算とみなされているのでonRerunがコールされる
  6. onBeforeAction, action, onAfterActionの順にコールされる。

(注1) subscribeは重複してコールしても動作上無視するようなので問題なさそうだが、お手製のready()ハンドルを作るとここで色々困る。github レポジトリのイシューに上がっている。

で、各フックの使い方ですが、

  • リアクティブでなくていいものはonRun
  • subscriptions/waitOnに依存しないものはonAfterAction
  • ページレンダリングの前に実行したいものはonBeforeAction
  • ページレンダリングの後に実行したいものはonAfterActionでthis.ready()がtrueの時

onAfterActionの実装が名前のイメージと違ってしまっているおかげでonRerunは使い道がなさそうです。

このタイミング仕様はわかりにくいし使いにくいので近いうちに変わるような気がします。

ただ、Iron Router開発が活発とは言えなくなっていて…

Flow Routerにi18nパッケージができたらみんなそちらに乗り換えてしまうかもしれませんね。

がんばれ、Iron Router!