Home > Latest topics

Latest topics 近況報告

たまに18歳未満の人や心臓の弱い人にはお勧めできない情報が含まれることもあるかもしれない、甘くなくて酸っぱくてしょっぱいチラシの裏。RSSによる簡単な更新情報を利用したりすると、ハッピーになるかも知れませんしそうでないかも知れません。

萌えるふぉくす子さんだば子本制作プロジェクトの動向はもえじら組ブログで。

宣伝。日経LinuxにてLinuxの基礎?を紹介する漫画「シス管系女子」を連載させていただいています。 以下の特設サイトにて、単行本まんがでわかるLinux シス管系女子の試し読みが可能! シス管系女子って何!? - 「シス管系女子」特設サイト

Page 4/248: « 1 2 3 4 5 6 7 8 »

RestartlessのE4Xレス化 - Dec 26, 2012

再起動の要らないアドオンをAdd-on SDK無しで開発するときの簡易的なテンプレートのような物として作っているRestartlessは、ツールバーボタンの定義や設定ダイアログの定義にE4Xを使う前提で設計してた。静的なXULファイルを別に用意しなくても、JavaScriptで書かれたロジックの中にリテラルとしてXULの定義を埋め込める、ということで重宝してたんだけど、E4Xのデフォルト無効化で完全にハシゴを外された形になってしまった。

E4Xを多用してた方々各方面悲喜こもごもあるようで、自力でスクリプトをパースしてCDATAマーク区間だけでも認識できるようにするとか色々なアプローチが試みられているようなのだけれども、僕はというと、面倒なのでE4Xはスッパリ諦める事にした。元はといえば、従来のやり方に近いやり方で再起動の要らないアドオンをラクに開発したいというのがRestartless開発の動機だったのだから、何か代わりの手段があるのであれば、E4Xにこだわる理由はなかったし。

まずE4Xで定義されたXULのコード片を受け取る部分についてだけど、これらは内部的にはXMLのソースコードの文字列に変換した後、RangeのcreateContextualFragmentでDOMDocumentFragmentにしてたので、インプットはただの文字列でも構わなかった。なのでToolbarItem.jsconfig.jsは以下の点だけ修正して終わりとした。

  • E4X無効の環境でもシンタックスエラーにならないように、E4X固有の書き方をなくした(具体的には、識別子としていきなり「*」が出てこないようにした)。
  • インプットが文字列の時は、それをそのままDOMDocumentFragmentにした後、ホワイトスペースだけのテキストノードをその都度削除するようにした(XBLの定義が手抜きなせいで、こういう場合に初期化エラーになるので)。

ツールバーボタンの定義は、手間だけど文字列リテラルに書き直すことにした(簡単なスクリプトでインデントも含めてそれっぽく置換した)。ちょよんごさんのnode-hereを移植することも考えたんだけど、単に改行込みのコード片を文字列として取得できるだけだと、E4Xの時みたいな「属性値やテキストノードの値にJSの変数の値を入れる」ということが簡単にはできなくて、そこの面倒さの方が気になったので、今回は見送ることにした。

ただ、設定ダイアログくらいの規模となると、一々文字列リテラルにしてたら埒があかないのでそこだけはなんとかしたかった。これについては、Firefox 8くらいから後のバージョンではchrome.manifestでcontentやlocaleのChrome URLを動的に登録・解除できるようになってるので、昔ながらのやり方に戻って静的なXULファイルで書くようにした

ロケールもこの要領でpropertiesファイルからDTDに書き直せばいいんだけど、Fox Splitterみたいにロケールの数が多いとそんなのやってらんないし、Fox Splitterの場合は設定ダイアログとブラウザ上のUIとで同じラベルを使い回したりしていて、どれをpropertiesファイルに残してどれをDTDにするのかとかを考えるのももう無理っぽかったので、逆転の発想で、属性値やテキストノードの値に{{ JavaScriptの文 }}という書き方を許容するようにして、XULドキュメントが開かれたときに自動的に解決するユーティリティを加えて、propertiesファイルをDTD代わりに使うことにしてみた。DOMContentLoadedのタイミングだと遅すぎるようだったので、今の所は待ち無しで実行してるけど、XBLの初期化タイミングが狂うリスクがあるので、将来的には問題が起こるかもしれない。(……と、ここまで書いて気付いたけど、node-hereを移植した上でこれと同じ記法を許容するようにすればよかったかなぁ。もう後の祭りだけど。)

Restartlessベースで作ってた各アドオン(親のタブに戻るFox Splitter、あと開発中で放置してた「Suspend Tab」)も更新済みで、masterベースのXPIはこの間から提供してる自動ビルドが既に利用できる状態になってる。Nightlyで使ってた人がもしいたら、これで動くようになってると思う。

……node-here.jsの移植はやらないでおくって書いたけど、結局やっぱり必要になってしまったので移植した。スタックトレースから列番号を取れないというGecko(SpiderMonkey?)の制限のため、1行の中に2個以上のhere()は書けない。

アドオンのナイトリービルドのようなものを置くようにした - Nov 24, 2012

リリースにまつわる諸々の作業が面倒くさくて、about:newtabには機能ができてすぐ対応したのに、リリースしてなかったせいで今頃「about:newtabを空のタブとして認識してくれないんだが」系の「不具合報告」が届くようになってきていて、他にも障害報告に対して「それmasterのHEADではもう直ってます」な場合が時々あって、あと時々「ナイトリービルドを提供してくれ」っていう声も見かけてはいたので、ちょっと頑張って/xul/xpi/nightly/でそれっぽい物を提供するようにしてみた。

  • 毎日定期的にリポジトリの変更をpullして、変更があったらXPIを作りなおしてアップロードする、ということを自動的にやってみてます。
  • 中身はmasterブランチのHEADをそのままパッケージングしただけの物で、typoで動かなくなってるような場合でもそのままアップロードしてしまうから、常用はお勧めしないでおきます。(とはいえ、この状態は僕自身の環境に極めて近いので、僕が常用しているアドオンについては、僕が不具合に遭遇し次第すぐに直すとは思いますが……)
  • 自動アップデートについては、リリース版とは別にこのナイトリービルド専用のupdate.rdfを提供するようにしてます。

どうやってるかというと、自宅にあるUbuntuマシン(NASも兼ねていて24時間動きっぱなしの自宅サーバ)上でcronjobを動かしているだけ。1点だけ工夫が必要だったのは、update.rdfに署名するという部分。update.rdfのデジタル署名にはMcCoyを使うんだけど、これだとcronjobとして自動実行させるのには都合が悪いので、MDNのページで紹介されてたMX-Toolsというのを使うようにした。

前提はこんな感じ。

  • アドオンのリポジトリはgitで管理している。
    • gitリポジトリには、パスワード無しの秘密鍵でSSH接続できる。もしくは、手元にリポジトリをパスワード無しでcloneしている(GitHubなら、httpsのURLを使ってcloneした場合がこれにあたる)。
    • すべてのリポジトリを、1つのディレクトリ(ベースディレクトリ)の中に、プロジェクト名と同じ名前のサブディレクトリでcloneしてある。
  • WWWサーバにはパスワード無しの秘密鍵でSSH接続できる。
  • RDFファイルの署名用にOpenSSLの鍵ペアを作成してある。
    • openssl genrsa -out keyfile.pem 1024
    • openssl rsa -in keyfile.pem -pubout -out keyfile.pub
    • 作成された秘密鍵・公開鍵はどちらもベースディレクトリ直下に置いてある。

特定の1つのアドオンについて「masterのHEADをpullして、変更があったらXPIにして、update.rdfを作って、アップロードする」というスクリプトは、試行錯誤の結果、こんな感じになった。

upload_nightly_xpi.sh:

#!/bin/bash

# MX-Tools等を同じディレクトリに置いているという前提で、
# このファイルのパスを基準にして、他のツールの位置を
# 指定するため、ディレクトリのフルパスを最初に得ておく。
tools_dir=$(cd $(dirname $0) && pwd)

remote_user=piro
remote_host=piro.sakura.ne.jp
remote_dist_dir=~/www/xul/xpi/nightly
actual_dist_dir=http://piro.sakura.ne.jp/xul/xpi/nightly

# ファイルの置き場所等はオプションで得る事にする。
while getopts ab:d:i: OPT
do
  case $OPT in
    # 変更が無くても強制的にアップロードする指定。テスト用。
    "a" ) always=1 ;;
    # keyfile.pem等を置いているディレクトリのパス。
    "b" ) base_dir="$OPTARG" ;;
    # リポジトリをcloneした先のディレクトリ。
    "d" ) project_dir="$OPTARG" ;;
    # SSH接続に使う秘密鍵のパス。
    "i" ) secret_key="$OPTARG" ;; 
  esac
done

if [ "$project_dir" = '' ]; then
  echo "no project directory specified"
  exit 1
fi

if [ "$base_dir" = '' ]; then
  echo "no base directory specified"
  exit 1
fi

if [ "$secret_key" = '' ]; then
  echo "no secret key specified"
  exit 1
fi

# sedのオプションの違いを吸収しておく。
case $(uname) in
  Darwin|*BSD|CYGWIN*) sed="sed -E" ;;
  *)                   sed="sed -r" ;;
esac

# pullした時のメッセージを見て、変更があったかどうかを調べる。
cd $project_dir
pull_result=$(git pull --rebase)
updated=$(if [ "$pull_result" != "Already up-to-date." -a \
               "$pull_result" != "Current branch master is up to date." ];\
          then echo "1"; fi)
if [ "$updated" = "1" -o "$always" = "1" ]; then
  package_name=$(cat $project_dir/Makefile | \
                 grep "PACKAGE_NAME" | \
                 head -n 1 | cut -d "=" -f 2 | \
                 $sed -e "s/\\s*//#")
  public_key=$(cat $base_dir/keyfile.pub | \
               grep -v -E "^--" \
               tr -d "\r" | tr -d "\n")

  # ナイトリービルド用として、install.rdfを書き換える。
  # バージョン番号の末尾に今日の日付を付ける。
  $sed -e "s/(em:version=\"[^\"]+)\\.[0-9]{10}/\\1/" \
       -i install.rdf
  $sed -e "s/(em:version=\"[^\"]+)/\\1.$(date +%Y%m%d)00.$(date +%H%M%S)/" \
       -i install.rdf
  update_rdf=${package_name}.update.rdf
  # 古いupdate.rdfが残っていたら消す。
  rm $update_rdf
  # update.rdfの参照先と、公開鍵を書き換える。
  $sed -e "s#/xul/update.rdf#/xul/xpi/nightly/updateinfo/${update_rdf}#" \
       -i install.rdf
  $sed -e "s#([^/]em:updateKey[=>\"]+)[^\"<]+#\\1${public_key}#" \
       -i install.rdf

  # 自動生成されたバージョン番号は、後で使うので控えておく。
  version=$(cat install.rdf | \
            grep "em:version" | head -n 1 | \
            $sed -e "s#[^\">]*[\">]([^\"<]+).*#\\1#")

  # ビルドした後、リポジトリの内容を元に戻しておく。
  # (次にpullする時に、未コミットの変更があるという
  # 警告が出ないようにする。)
  make
  git reset --hard

  file=$(ls *.xpi | grep -v "_noupdate" | head -n 1)
  # キャッシュが使われる事の無いように、
  # ユニークなダウンロード用URLにする。
  update_link=${actual_dist_dir}/${file}?version=${version}

  if [ "$file" != "" -a -f $file ]; then
    ssh_remote=${remote_user}@${remote_host}
    # 公開先のディレクトリを作っておく。
    ssh -i $secret_key ${ssh_remote} \
        mkdir -p ${remote_dist_dir}/updateinfo
    # XPIをアップロードする。
    scp -i $secret_key ./$file \
        ${ssh_remote}:${remote_dist_dir}/
    # XPIからupdate.rdfを自動生成し、それもアップロードする。
    $tools_dir/mxtools/uhura -o $update_rdf \
      -k $base_dir/keyfile.pem $file $update_link
    scp -i $secret_key ./$update_rdf \
        ${ssh_remote}:${remote_dist_dir}/updateinfo/
  fi
fi

exit 0

uhuraを使うには、依存パッケージを入れておく必要がある。

$ sudo apt-get install openssl unzip libexpat1-dev
$ cpan
(色々セットアップ。基本的には全部YesでOKだと思う。)
$ sudo cpan install  XML::Parser RDF::Core Digest::SHA1 Convert::ASN1

アドオン1つだけでテストしてみた。

$ ./upload_nightly_xpi.sh -b ~piro/xul \
                          -d ~piro/xul/autodisableime \
                          -i ~/.ssh/id_rsa.nopassword \
                          -a

これでうまく動くことを確認できたので、複数リポジトリを全部処理するスクリプトを作って、そちらをcronで走らせるようにした。

upload_nightly_xpis.sh

#!/bin/bash

tools_dir=$(cd $(dirname $0) && pwd)

# 鍵の指定などを丸ごと引き渡すようにしたいので、
# このスクリプト自身では使わないオプションについても
# 受け付けるようにしてる。
while getopts ab:d:i: OPT
do
  case $OPT in
    "b" ) base_dir="$OPTARG" ;;
  esac
done

if [ "$base_dir" = '' ]; then
  echo "no base directory specified"
  exit 1
fi

cd $base_dir
for dirname in *
do
  if [ -d $dirname ]; then
    ${tools_dir}/upload_nightly_xpi.sh -d $base_dir/$dirname "$@"
  fi
done

で、これを日に2回動かすよう、crontabに 0 7,19 * * * upload_nightly_xpis.sh -b ~piro/xul -i ~/.ssh/id_rsa.nopassword とかいう感じで書いてる。

仮想マシンでも何でもいいけど、Linuxな環境があると自動化がはかどるな……と思いました(手前味噌)。

2012年11月26日追記:スクリプトにミスがあってinstall.rdfに埋め込む公開鍵が置き換わっていなかったので修正した。

Tabs Outlinerとツリー型タブ - Sep 21, 2012

Tabs OutlinerというGoogle Chrome/Chromium用拡張機能がある。説明をよく読むと、Firefoxでツリー型タブを使っていた人が、Google Chromeに乗り換えるにあたって作った物らしい。

以前試した時は、リンクからタブを開いてもツリーが構築されないというのが「えっ」という感じであんまりよく試さないでアンインストールしちゃったんだけど、今日なんとなくまたインストールしてオプションを開いてみたら「Tree Style Tabs」ってチェックボックスがあって、そこに書いてあった説明を見たら「これONにしたら自動でツリーになるようになる」的な感じっぽかったので試してみたら確かにリンクから開いたタブが勝手に子タブになってくれた。

ということで、ツリー型タブにロックインされてしまってるせいでFirefoxからGoogle Chromeに乗り換えられないという人(時々そういう話を目にするのです)にとってこれはマジに救世主になるかもしれないなと思ってもうちょっとだけ試してみてた。タブの切り替えがダブルクリックじゃないとだめだったり、他の拡張機能との連携はさすがにできないっぽかったり、Google Chrome本体のメニューから終了したらツリー構造が保存されなかったりで、僕自身が乗り換える先としては厳しいなあ……とは感じたけど、そういう所が気にならない人なら、普通に使えるんだと思う。

そんな「Tree Style Tabs」モードなんだけど、チェックボックスの下にすごく長い注意書きが付いてた。僕が読み取れた大意としては、「そういう要望がものっそ沢山寄せられるから機能を付けてるけど、自分(作者)はこのモードはお薦めしない。試してみてもいいけど、このモードだけで使うんじゃなくて、このモードをOFFにしたTabs Outliner本来の状態でも是非使ってみて欲しい。」ということが書いてあるようだった。同様のことがTabs Outlinerの配布ページにも書いてあって、作者の人によると、ツリー表示は情報の一覧性が悪くて、フラットなタブのリストの方が可読性が高いぞ、と。ツリー、ずいぶん嫌われたもんですね……

この見解の違いは、タブとタブのツリーという物をその人がどう捉えているのか? という所から生じているのだと思う。

僕にとって、タブのツリーは(生存期間は短いけれども)ある情報を起点にしてあちこちさまよい歩いた足跡そのものであって、どのページからどのタブへ辿り着いたのかが視覚化されているということが非常に重要だ。僕はその関係性を目で追って「分かれ道になったノードはどれだったっけ」と探している(ちなみに、この時見ているのは主にfaviconと情報化タブが提供するサムネイルで、タブのラベル文字列は注視していない)。1階層のグループ化しかできないPanoramaだけでは不十分なのは、「新しいタブを開いて分かれ道になったノードがどれだったか」という情報が欠落してしまうからだ。

そのくらい憶えておけよって言われるだろうけど、僕はほんとに頭が悪いというか物覚えが悪いというかバカなので、「そのくらい」がもう悲しいくらい絶望的なほどに覚えられない。覚えられないから、そのまま視覚化して置いておく。僕にとってタブのツリーは、脳に収まりきらない情報を置いておく外部記憶になっていると言える。メインメモリの中に情報が乗り切らなくて、画面の中にしか置いておけないのだから、多少アクセス速度が遅いとしても、そこに置いてある情報を毎回取りに行く。そういう使い方をしていると思う。

でも、「そのくらい」を覚えるのが苦にならない人にとっては、オーバーヘッドが大きすぎてまどろっこしいのかもしれない。タブ同士の関係はこぼれることなくメインメモリの上に載りきっているから、わざわざ画面の中にまで同じ情報を残しておく必要性が無い。そういうことなんじゃあないだろうか、と思う。

極端なことを言えば、ツリー型タブというのは脳味噌の性能が極めて低い障碍者がフツーの人に後れを取らないように、フツーの人に合わせて作られた社会の中で日常生活を送るために不足分を補うために使う、義肢とか車椅子とかそういう物に相当するのかもしれない。電動車椅子に乗れば確かに誰でもラクに移動できるけど、自分の足で立って歩ける人は、車椅子を降りて歩いた方が自由にもっといろんな所に行ける。また、電動車椅子に慣れきってしまうと、脚がひなびて自力で立てなくなってしまうかもしれない。使わなくても生きていけるなら、使わない方が健康でいられるのかもしれない。ツリー型タブという物については。

Mozilla勉強会@東京 7th 発表資料を公開しました - Aug 19, 2012

Mozilla勉強会@東京 7thでの発表資料やサンプル実装を公開しました

発表時は準備不足のため時間の配分に失敗し、満足な説明を行えませんでした。すみません。発表時に喋ろうと思っていた内容のメモも併せて公開していますので、そちらもご覧頂ければと思います。

続きを表示する ...

The priority policy of my addon projects - May 10, 2012

In recent days, I discussed on the issue about scrolling of the vertical tab bar. It made the priority policy about my addon projects clear, again. So, let's sum up them.

  • I assign the highest priority to issues I actually annoyed. Most projects were started because I wanted to use such addons. This is the main motivation to continue developing for me. In other words, when I suffer from a bug in my daily use, I'll fix it prior to other bugs, even if the mine is just trivial and the yours is very serious. After that, if I have time good enough, I'll research and fix your issues. If I've never used the feature (and I never use it in the future), then there is extremely low feasibility rating.
  • I'm negative about adding new features (especially digressive features) to existing addons. Because I currently have no plan to switch to other browsers (Google Chrome, etc.), I want to keep codes easy to follow up to future releases of Firefox. Even if the new feature looks simple, it can cost much time for maintenance in the future chronically. Long term sustainability is prior to short term convenience, for my projects. I'll reject requests which can lose maintainability or independency of the project, even if it is very useful feature, fixing serious bug, and so on.
  • I think that any addon shouldn't break features of Firefox itself without any apparent reason. For example, because the tab bar is automatically hidden in the full-screen mode (F11 key) by default, the vertical tab bar also should be done. If my addon breaks Firefox's default behavior unexpectedly, then I'll make effort on fixing it. However, if the issue is not introduced by my addon, then I often step back from it.

Because currently I have less time to develop addons, I have to apply these policies strictly. Actually, in recent days, I spend just a few days of my time per a month for my private development. Sadly I have to keep many requests pending.

However, codes of my addons are licensed under open source licenses. For example, Tree Style Tab is licensed under GPL/LGPL/MPL. You can fork, develop, or re-distribute any project based on my codes, by your hand. Your version can be better alternative for people who suffered from the issue ignored by me. (And, if it is enough reasonable, I possibly merge your changes to my repository.)

Fox Splitterを更新した - Apr 23, 2012

バージョン0.6系(旧版)2.x系(現行バージョン)の両方とも更新した。

バージョン0.6系の方は、前に書いた2.x系への自動アップデート機能の追加だけで、他は何もいじってない。AMOからインストールした人が2.x系に自動アップデートされないという問題への対処のためだけに作ったバージョンなので、AMOにしかアップロードしてない。基本的にこっちはもう終了したバージョンということでよろしく。

2.x系の方は、最近になってUbuntu上でヘビーに常用し始めるようになって色々気付いた問題を修正したのと、僕の使い方で「ああこういう機能欲しいやばい(ないとめんどい)」と思った機能を追加した。

修正の方で特に大きいのは、「グループ化されたウィンドウの1つを移動した後に他のウィンドウをそれに併せて移動する」という部分の改善だと思う。

GNOME2のワークスペース切り替えの時はそこまで酷いことになってなかったんだけど、Ubuntu 11.10にアップデートして3×3のワークスペースを使うようにし始めた(これ多分GNOME3の機能ですよね?)ところ、全く使い物にならないレベルでグループの配置が壊れるようになってしまった。GNOMEのワークスペース切り替えは、少なくともFirefoxの中から見た時には、各ウィンドウの座標を固定してビューポートの方だけを移動させるんじゃなくて、ビューポートの座標の方を固定して全部のウィンドウの座標をぐりぐり動かしているように検知されている。なので、ワークスペース切り替えの時に全部のウィンドウのscreenX/screenYの値が変わってしまう。それで、それぞれのウィンドウがてんでバラバラに「グループの中のウィンドウが1個動かされたから他のウィンドウも再配置しよう」という事を始めてしまってシッチャカメッチャカになっていた。

「グループ化されたウィンドウ全部が相対座標を保ったまま一度に移動されたので、再配置の必要なし」とかの判断をちゃんとするようにすればよかったんだけど、僕の頭で思いつくやり方だとどーにもうまくいかんかったので、諦めて安全確実だけどちょっと重い方法でウィンドウの移動→グループ全体の再配置を行うようにした。普通にウィンドウをドラッグで移動した時とかのレスポンスは悪くなったんじゃないかと思うけど、背に腹は代えられない。

新機能は、「グループ化されたウィンドウの1つでPanoramaを使った時に、グループ全体の大きさまでそのウィンドウを一時的に広げる」という機能が元々あったのを、Panoramaの時以外にも使えるようにした(ついでに、詰めが甘かった所を色々直した)という物。何でこういう物が欲しかったかというと、

  1. 僕は今Ubuntuのワークスペースの1つをFox Splitterで3分割したFirefoxのウィンドウ専用に割り当てている。
  2. 分割後のそれぞれのウィンドウには、別々のプロジェクトのRedmineのチケット一覧を表示している。
  3. それぞれのプロジェクトでチケットを追加する時は、その分割されたウィンドウの中でやっている。
  4. Redmineはある程度の大きさのウィンドウで表示される前提でレイアウトが組まれているので、狭いウィンドウの中では非常に使いにくい。
  5. なので、チケットを書いたり詳細を読んだりするときだけそのウィンドウを大きくして、終わったら元の大きさに戻す(そうしないと他のウィンドウのRedmineが見えないから)という事をよくやっていた。

という使い方をしていて、いいかげんいちいち自分でリサイズするのが面倒になったから。

今のFox Splitterは、全体を管理する大きなウィンドウのような実体が無い状態で各ウィンドウをあたかも1つのグループの下に属しているかのように協調して動作させる、ということをやっていて、作ってる側の自分としては、頭を抱える部分も多いけれども「元々Firefoxにある物だけを駆使してどこまでできるか?」ということを追及するある種の挑戦というかパズルに挑んでいるような感覚もあって、そういうことを効率よくやるためには結局2分木でやるのが安全確実なんだなあとか色々と気付かされた所があって、ノウハウ的にも自分のやってきたことの集大成になってるんだけど、エンドユーザとしての使い勝手は多分旧版のFox Splitterに比べると劣化してると受け取られることの方が多そうで、報われないことに一生懸命になってるなー感が自分である。

とはいっても、自分で使う分にはとりあえずこれだけ動いてくれれば十分だし、旧版の設計で今後もずっと自分でメンテナンスし続けるのは絶対に無理だし、もっといいやり方が見つかるまでは、この路線を変えることは多分無いと思う。

Ez Sidebarを数年ぶりに更新した - Apr 07, 2012

とかなんとか発言した舌の根も乾かないうちにEz Sidebar 4.0.2012040701を公開した。実験的にやってみたら案外あっさりできたので、その勢いで完成まで一気に。実質的にほぼ0からのスクラッチで、基本設計が全く別物になっていてコードの共有部分はほとんど無い。

旧版ではサイドバー用のウィンドウを物理的に(DOMツリー的に)別ウィンドウとして開いていて、パネル内のスクリプトに対してどうやってブラウザウィンドウの中にあるように見せるかという所が技術的な鍵だった。例えばwindow.parent.gBrowserにアクセスされたら、最も手前にあるブラウザウィンドウを探してきてそのgBrowserを返す、みたいな感じで。そういう強引なことをやってたから、つくづく、よくあんなんで動いてたなという感じだ。

今回の再実装では、根本的な考え方は至極単純で、ウィンドウの内容が初期化されるタイミングで<panel>の中にサイドバーのボックスを丸ごと移動して、以後はその<panel>を「別ウィンドウに切り離されたサイドバー」として表示している。これだとサイドバーは相変わらず元のウィンドウのDOMツリーの中に存在しているから、パネル内のスクリプトから見た時に普通に親のフレームとしてFirefoxのウィンドウにアクセスできるし、Firefoxのウィンドウの側からもパネルの内容を普通にサブフレームとして認識できる。Firefoxのウィンドウが複数ある時は最前面のウィンドウの<panel>だけを表示しておき、ウィンドウが切り替わったタイミングで同じ位置・同じ大きさに<panel>を表示する、という事をやってるので、見た目的には1つの<panel>が個々のFirefoxのウィンドウとは独立して存在しているように見えなくもない。他にも、ドラッグ操作での移動とかリサイズとか、ただの<panel>をウィンドウっぽく動かすために細かい所で違和感が出ないように色々やってる。

何故旧版では<panel>を使わなかったのかというと、やりたくてもやれなかったんですよ。サイドバーは一種のインラインフレームなんだけど、確か昔は<panel>の中にインラインフレームを置くとまともに動作しなかったと思う。そういう細かい技術的な障壁が当時は色々あって、Ez Sidebarのような事をどうしてもやりたいとなると、旧版のようにダーティなハックをたくさん仕込まないといけなかった。それが今では、「こう書いたらこう動いて欲しいよね」という書き方をすればだいたいフツーに動いてくれるわけですよ。隔世の感だ。

あと、バージョン3.2(1つ前のバージョン)にあった機能を全部引き継いでるわけではなくて、というかサイドバーをメインウィンドウから切り離して表示する機能以外は全部バッサリ切り捨てた。All-in-One Sidebarのような有名所のアドオンが既にそういう機能を持ってるみたいだから、わざわざ同じ機能を作らなくても、そっち使えばいいじゃんという話です。Ez Sidebarは、他のアドオンが提供してくれない機能だけに絞って提供した方が意義があるはず……と思って。

過去にこのアドオンの名前を「Sidebar Window」から「Ez Sidebar」に変えたのは、サイドバーの切り離し以外の機能も色々付けたからだったんだけど、今回のリリースで機能的には最初の物より低機能な所に逆戻りしてしまった。皮肉な結果だ。

Fox SplitterのせいでユーザのFirefox 3.6からの移行が進まないって言われた件 - Apr 02, 2012

Linuxでwmctrlを使うようにしたバージョンのFox Splitterを今日付で公開した。

なんだかんだで最近腰が重いんだけどその重い腰を上げてリリースのための作業をやろうと思った背景の1つには、Mozillaの中の人からメールで表題の件について連絡があったからだ。既知のバグがあってmasterでは直ってるのにリリースされていない、という状況ではそのメールに返信するのが憚られる……と思って、慌てて細かい所を直してリリースしたというわけ。これも罪悪感駆動開発な気がする。

Fox Splitterのユーザが古いバージョンを使い続けている最大の理由は、AMOでFox Splitter 0.xから2.0への自動アップデートが行われないからじゃないかと思ってる。諸々の事情でFox Splitter 2.0では旧版からアドオンのIDを変えないといけなかったので、AMOのサイト上ではFox Splitter 2.0と0.xが別々のアドオンとして登録されてて、Fox Splitter 0.xのユーザにはFox Splitter 2.0が自動アップデート経由で提供されない。2.0への移行は、完全にユーザの自由意志に任せざるを得ないという事になっている。使い勝手がどうとか以前に、勝手にアップデートが下りてくるかこないかがネックになってるっていう予想だ。

強権的手段として、「単にFox Splitter 2.0を自動的にインストールして、その後Fox Splitter 0.xを削除する」というだけの内容のアドオンをFox Splitter 0.x最新版としてアップロードすれば、Fox Splitter 0.xから2.0への移行を強制することはできるけど……2.0の方には否定的なレビューが多く付いていて評価も低い(旧版は星2つ以下は15%なのに対し、新版は星2つ以下が57%……まあ母数が圧倒的に少ないから統計的にはあんまり意味がないかもなんだけど)という現状を見ると、そこまでやっちゃっていいっていう自信をまだ持てずにいる。

4月4日追記。Mozillaの中の人から「ちょうどそういう(Fox Splitter 0.x系の新バージョンとして、Fox Splitter 2への自動アップデート機能を含んだ物をリリースするという)方法について提案しようと思ってた所だった」的なレスポンスがあったので、春の嵐で早退したのをいいことに頑張って書いてみたんだけど、死ぬほどめんどかった。

Fox SplitterのLinuxでの挙動の改善と、Mac OS Xで残された課題 - Mar 25, 2012

Fox SplitterをWindows以外で使った時に 実にパネェ感じでストレスフルな挙動を示す件について、とりあえずLinuxではちょっとだけ改善できた気がする。

要点を先にまとめておくと、こういうことだ。

  • Windows上では以前から、ウィンドウの1つが選択されて最前面に来たら、グループ化された他のウィンドウもそれによって「押し上げられ」て最前面に来る、という挙動になっていた。
  • でもFirefoxの仕様上の制限で、LinuxとMac OS Xではそれができていなかった。
  • 今回、Linuxではwmctrlを呼び出すことによってWindows上と同じような挙動を再現できるようになった。
  • Mac OS Xで同じ事ができるのかどうかは分からないままである。
  • JSDeferredはやっぱり素晴らしいです。

以下、背景も含めた詳しい話。

続きを表示する ...

tabFx2Compatible.xul、tabFx2Compatible.css、tabFx2Compatible.xmlを使わないようにした - Feb 09, 2012

ツリー型タブ情報化タブの今日付でのリリース分から、tabFx2Compatibleという自作のライブラリ(?)を使わないようにした。当初はマルチプルタブハンドラでも使ってたけど、ツリー型タブ・情報化タブに先駆けて一足先に使わないようにしていた。今回残りの2つでも利用をやめたことで、TBEやり直し組のアドオンからはこのライブラリが全く姿を消したことになる。作ったのが2008年の2月からだから、丸4年くらいは使ってたのか。

このライブラリは元々、Firefox 3での仕様変更に追従するために仕方なく作った物だった。

Firefox 2ではタブの中に任意の要素(サムネイル描画用のcanvasだったりカウンタ表示用のlabelだったり)をXBLのコンテナ要素を使って動的に追加できていた。しかしFirefox 3になる時、具体的には2007年の12月頃に、高速化のためにそういう冗長性を排除する変更が行われてしまって、JavaScriptで動的にタブの内容を追加するということが原理上不可能になってしまった。

正確には、方法はあった。Firefox本体がタブに適用していたXBLによるバインディングを独自のバインディングで置き換えて、それを使ってタブの内容を変更するというやり方だ。しかし、XBLのバインディングは同時に1個だけしか適用できないという制限がある。複数のアドオンが同じ事をやろうとしたら、結局どれか1つのアドオンしかまともに動かないという事になってしまう。他の人の作る物との互換性という話に限らず、リッチでファットなAll-in-One型のアドオンであったTBEを捨てて各機能ごとに個別のアドオンに開発し直す道を選んでいた僕にとっては、自分の手がける物同士の互換性を維持するためにも、これは致命的な問題だった。

前述のライブラリは、特定のアドオンのために特化したバインディングを適用するのではなく、Firefox 2時代の「ある程度好きなようにタブの内容を増やせる余地がある」、冗長性を持った汎用的なバインディング定義を、Firefox 3向けに復活させるという物だった。

風向きが変わったのは2010年9月の事だった。Firefox 3.7のモックアップで示された視覚的なデザインを実現するために、タブのバインディングに再び冗長性が付与された。メジャーバージョンとしては、この変更はFirefox 4から反映されている。僕はこの仕様変更をうけてtabFx2Compatibleを改修し、Firefox 4以降のタブのバインディングの構造と、Firefox 2以前のタブのバインディングの構造の、両方を併せ持つ状態に変更した。

という経緯を見ると分かるかもだけど、このtabFx2Compatibleというライブラリは本質的に、Firefox 3.0から3.6までの間のバージョンに対応するためには欠かすことができなかった。ツリー型タブ等のアドオンの対応バージョン範囲の下限がこの範囲に重なっている間は、このライブラリは絶対に使う必要があったので、いくらTMPやVimperator等とバインディングの衝突の危険性があったとしても、構成ファイル群から外すことができなかった。

今回、Firefox 10のESR(延長サポート版)がリリースされたことにより正式にFirefox 3.6の死期が確定したので、サポート終了を待たずにFirefox 3.6のサポートを打ち切って、それと同時にtabFx2Compatibleも廃止することにした。レガシーなFirefox 2由来のDOMツリー構造を前提にして書かれたスクリプトやスタイルシート等を、全面的にFirefox 4以降の既定のDOMツリー構造に合わせて変更する作業は、それなりの手間を要したけれども、これでカビの生えた過去から決別できるのなら安い物だと思った。

選択肢の1つとして、tabFx2Compatibleを今後も使い続ける(Firefoxのタブのバインディングの構造が変わったら、その度にtabFx2Compatibleを更新していく)というやり方もあった。今この瞬間にかける労力を最小化する事を選ぶのなら、そういう選択もあり得たと思う。でも、tabFx2Compatibleは元々Firefox 3から3.6までの暗黒期を乗り越えるためだけに用意された物だったのだから、用済みになったのなら、思い切って捨てた方が今後のためになると思った。

こういう切り替えをできる時にやっておかないと、またTBEみたいな事になってしまう恐れがある。TBEでは、タブの移動等といった基本的な機能すらFirefox本体に備わっていなかった頃から開発していたため、TBE自身で独自の「タブを移動する」などのAPIを実装していた。そういう古いオレオレAPIから、Firefox 1.5くらいから新しくFirefox本体に備わったTabMoveとかのDOMイベントベースでのやり方にスイッチする事の手間を惜しんで、「とりあえず今動いてるから」と独自のオレオレAPIを維持することに固執してしまったがために、TBEはFirefox 1.5とともに時代に取り残され死んでしまった。そんな愚はもう繰り返してはいけない。

それにつけても、あの辺(Firefoxのタブまわり)の開発をやってる人達の意向に振り回されっぱなしだった4年間だったなー……と思うと、なんか感慨深い。

Page 4/248: « 1 2 3 4 5 6 7 8 »

Powered by blosxom 2.0 + starter kit
Home

カテゴリ一覧

過去の記事

1999.2~2005.8

最近のコメント

最近のつぶやき