Home > Latest topics

Latest topics 近況報告

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

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

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

Page 11/26: « 7 8 9 10 11 12 13 14 15 »

XPCOMのインターフェースの変更点 on Firefox 3.1と、正規表現検索のアドオン - Jan 30, 2009

落ち穂拾い #6 - Mozilla Fluxで、Firefox 3.0から3.1(beta3前まで)のXPCOMコンポーネントのインターフェースの変化まとめが紹介されてたので見てみた。これはすごいな……だいぶ確認の労力を削減できるんじゃないか? まあインターフェースが変わってなくても実装が変わって影響が出てる、という箇所もひょっとしたらあるかもだけど、大まかなチェックには使える。

ところでこのサイトどっかで見たなと思ったら、Nightly Tester Toolsの作者の人だった。でアドオン一覧のページがあったから見てみたら、/Find Bar/という気になる名前があった。ページ内検索で正規表現を使えるようにする、という物だ。ってこれ、XUL/Migemoともろかぶりじゃん!! 中身見てみたけど、やってることはやはり同じような感じだった。参考にできる所があったらパクらせて貰おう(GPL/LGPL/MPLのトリプルライセンスなので、GPLのXUL/Migemoにはコードを取り込める)。

しかし「Migemo」といい「/Find Bar/」といい、「正規表現(regexp)」というキーワードからはなかなか見つけられない名前なのが困りものだ。

安全なタブの取得方法 - Jan 24, 2009

前のエントリでも触れてるけど、Firefox 3.1ではタブでない要素がタブバーに入る可能性が出てきたので、安全なタブの取得方法を色々考えてみた。

まず、すべてのタブのリスト。

function getTabs(aTabBrowser) {
  return aTabBrowser.ownerDocument.evaluate(
    'descendant::*[local-name()="tab"]',
    aTabBrowser.mTabContainer,
    null,
    XPathResult.ORDERED_NODE_SNAPSHOT_TYPE,
    null
  );
}

var tabs = getTabs(gBrowser);
for (var i = 0, maxi = tabs.snapshotLength; i < maxi; i++) {
  alert(tabs.snapshotItem(i).label);
}

配列でないと困る時はこう。

function getTabsArray(aTabBrowser) {
  var tabs = getTabs(aTabBrowser);
  var array = [];
  for (var i = 0, maxi = tabs.snapshotLength; i < maxi; i++) {
    array.push(tabs.snapshotItem(i).label);
  }
  return array;
}

特定のタブの「次のタブ」。

function getNextTab(aTab) {
  return aTab.ownerDocument.evaluate(
    'following-sibling::*[local-name()="tab"][1]',
    aTab,
    null,
    XPathResult.FIRST_ORDERED_NODE_TYPE,
    null
  ).singleNodeValue;
}

特定のタブの「前のタブ」。

function getPreviousTab(aTab) {
  var tabs = aTab.ownerDocument.evaluate(
    'preceding-sibling::*[local-name()="tab"]',
    aTab,
    null,
    XPathResult.ORDERED_NODE_SNAPSHOT_TYPE,
    null
  );
  return tabs.snapshotItem(tabs.snapshotLength-1);
}

preceding-sibling軸を使った時の返り値のノードの並びは軸方向の出現順ではなく文書順になるので、注意がいる。

function getPreviousTab(aTab) {
  return aTab.ownerDocument.evaluate(
    'preceding-sibling::*[local-name()="tab"][1]',
    aTab,
    null,
    XPathResult.FIRST_ORDERED_NODE_TYPE,
    null
  ).singleNodeValue;
}

タブの個数、最初のタブ、最後のタブも。

function getTabCount(aTabBowser) {
  return aTabBrowser.ownerDocument.evaluate(
    'count(descendant::*[local-name()="tab"])',
    aTabBrowser.mTabContainer,
    null,
    XPathResult.NUMBER_TYPE,
    null
  ).numberValue;
}

function getFirstTab(aTabBowser) {
  return aTabBrowser.ownerDocument.evaluate(
    'descendant::*[local-name()="tab"][1]',
    aTabBrowser.mTabContainer,
    null,
    XPathResult.FIRST_ORDERED_NODE_TYPE,
    null
  ).singleNodeValue;
}

function getLastTab(aTabBowser) {
  return aTabBrowser.ownerDocument.evaluate(
    'descendant::*[local-name()="tab"][last()]',
    aTabBrowser.mTabContainer,
    null,
    XPathResult.FIRST_ORDERED_NODE_TYPE,
    null
  ).singleNodeValue;
}

こういう時自分はついついXPathを使ってしまうんだけど、速度的にはどうなんだろう。ちゃんと計測してないから分からない。Array.slice(gBrowser.mTabContainer.childNodes).filter(function(aNode) { return aNode.localName == 'tab'; })とかの方が普通に速かったらごめんなさい。

childNodesを参照してるコードがヤバイというのはホントに酷い話だなあと思うけど、Google ChromeやIE7以降と同じユーザ体験を実現しようと思ったらどっかの時点でこれには手を出さなきゃいけなかった訳で、もうみんな腹括って粛々と受け入れるしかないんじゃないかと思うんだなあ僕は。

追記。例によってきっとガン無視されるだろうけどバグ立ててみた

追記。どうやら僕が立てたバグに関しては杞憂だったみたい……そもそもこのエントリに書いた話も今回の修正以前から潜在的にはあった問題のようだし。むしろヤバイのはalice0775氏が着目してる問題で、実際のノードの並び順と表示される順番とが食い違うことがあるようだ。この手の問題は僕も過去にXBLで色々試してた時に遭遇して、諦めて「こういう事はしない」という風に自分ルールで決めた記憶がある。バックアウトするのもいいけど、そもそもこれはXBLの匿名内容のレイアウトに絡む根深い問題に起因してるようなので、ここらで誰かが本気出して低層の所を直してくれないことにはどうにもならん気がする。

26日追記。「実際のノードの並び順と表示される順番とが食い違う」件は、新しいNightlyを試したら再現しなくなった。僕の全面的な勘違いだったのか、それとも別の所で修正されたのか…… あとgetBrowser().mTabContainer.selectedIndex プロパティと getItemAtIndex メソッドじゃあダメなのかなと言われたので調べてみたけど、現状のgetItemAtIndex()childNodes.item()のエイリアスに過ぎないようなので、やはり万全を期すなら別の手(このエントリに書いたような)を考えておいた方がいい気はする。

MozStorageを使う時にメモリリークを防いだりオーバーヘッドを減らしたり - Jan 09, 2009

mozIStorageStatement.finalize() メモ - 1/4ガロン

うっ。僕の知識は古かった。Firefox 3 Hacksで、createStatement()で作ったステートメントは使い終わったらstatement.reset()、と書いてましたが、statement.finalize()が正解だったようです。

が、一律にこう置き換えるとよい、というわけでもないのがややこしい所です。mozIStorageStatementのfinalizeメソッドはどうやらFirefox 3.0.x(Gecko 1.9)で導入された物のようで、Gecko 1.8系では存在しません。なのでメソッドを呼ぶ前に存在確認をしておかないといけない。Firefox 2なんてもうサポート終了してんじゃん!と思うかもですが、Thunderbirdはまだ2.0.0.xが現役なのでもうしばらくは気をつけないといけないんですハイ。

ところで、僕はずっと誤解してしまってたんですが、ステートメントはstatement.reset()でリセットすると、バインドするパラメータを変えて何度も使い回せるんですね。createStatement()のオーバーヘッドがどのくらいなのかよく分からないのでアレなんですが、SQL文が変わらない時はキャッシュしたステートメントを使い回すようにするという形で、高速化を図れるでしょうか。XUL/Migemoに早速活かしてみたいと思います。

FXツールバー - Nov 10, 2008

ツリー型タブクリック証券のFXツールバーが衝突しているという話を見かけたので調べてみたんだけど、だいぶお手上げです。

  • 原因は、クリック証券のFXツールバーが、初期化処理の中でXMLHttpRequestの同期読み込みを使っているせいである。
    • 同期読み込みを行っている間、ツリー型タブを含む他のアドオンの処理がすべてストップしてしまう。
    • ツリー型タブはセッション復元のイベントを捕捉してツリー構造を復元している。正常な状態では、こうなっている。
      1. ツリー型タブの初期化処理が始まる。セッション復元関係のイベントの監視が始まる。
      2. セッション復元関係の処理が行われる。
      3. ツリー型タブがセッション復元関係のイベントを捕捉し、ツリー構造を復元する。
    • しかしFXツールバーが入っている場合はこうなる。
      1. FXツールバーの初期化処理が始まる。同期読み込みのために処理が止まる。
      2. セッション復元関係の処理が行われ、完了する。
      3. 同期読み込みが完了し、FXツールバーの初期化処理が終わる。
      4. ツリー型タブの初期化処理が始まる。セッション復元関係のイベントの監視が始まる(が、もはや手遅れ)。
  • FXツールバーの初期化処理を書き換えてみようと思ったけど、変数スコープの関係で、ツリー型タブの中からFXツールバーの初期化処理を書き換えたら全く動かなくなってしまう。
  • FXツールバーの初期化処理が走る前にセッション復元イベントの捕捉を開始して、ツリー型タブの初期化が終わる前に起こったイベントはすべてキューに溜め込み、ツリー型タブの初期化が終わった後でそのキューを処理する、という風にしてみたけど、タイミング次第ではまだ復元に失敗する。

リバースエンジニアリング禁止とあったけどべつに僕はこれを利用するつもりも使用するつもりもないのであくまで自作アドオンとの競合の原因を調査するために難読化されたコードを頑張って解読してみたところ、FXツールバーは非同期処理のための便利メソッドを持ってるくせに何故か初期化の時は同期処理にしているという事が分かった。何故そんなところで手を抜くんだ……

サーバからの設定の読み込みを非同期で行って、設定の読み込み完了後に初期化処理の続きを行うようにすれば、この問題は解消されると思うんだけど。ツリー型タブ以外にも物によっては衝突する可能性があるし、向こうの方で対処してくんないかなあ。望み薄かなあ。一応問い合わせ先のアドレス宛にメールしてみたけど……

続報。返信があり、初期化処理を非同期で行うように改良された新バージョンがもうすぐ公開されるとのことです。反応はやっ!(僕がメールするより前から準備してたっぽい?)

Firefox 3.1で入りそう・もう入ること確定の変更点 - Oct 27, 2008

前者は3.1ブロッキングにもなってないし確定というわけではないようだけど、影響範囲があまりにでかくて入れば僕の作ってる奴も全滅は間違いないので注視しておきたい。

後者はもう入ってるので、見落としが無いようにパッチの隅々までチェックしておかないと。

ていうかほんとMozillaの世界の「ベータ」ってアテにならない表現だよね……ファイナルベータでアルファ版級の変更をぶち込んできたりとかさ。

ウィンドウ間でのタブの移動、というか、フレームの内容の入れ換え - Oct 19, 2008

Firefox 3.1からは、ウィンドウをまたいでタブを移動できるようになる。アドオンの作者はこれに合わせて修正を行わないといけない場合がある。

また、この機能を実現するために新しく用意された「表示されている2つのフレームの内容を破壊せずに入れ換える」APIは、他の目的でも利用することができる。

続きを表示する ...

旧ドラッグ&ドロップAPIから新ドラッグ&ドロップAPIへの移行 - Oct 02, 2008

Fx3.1b1pre tabbrowser全滅で報じられているとおり、Bug 456048 – Use the new D&D API in tabbrowserによって、tabbrowser要素のドラッグ&ドロップ関係の処理がHTML5で定められた仕様に基づいたものに変更されたようだ。

新APIの使い方についてはGomitaさんが分かりやすい解説を連載で書いてくださっているので、そちらを見てもらうとして。

パッチを見た感じでは、可能な限り最小の変更で新APIに移行していたので、ツリー型タブにも手を入れてみた。変更点を見ると分かるけど、以下のようにしている。

  • メソッド名の変更に追従した。
    • onDragStart_onDragStart (ツリー型タブでは触ってないけど)
    • onDragOver_onDragOver
    • onDragExit_onDragLeave
    • canDrop_setEffectAllowedForDataTransfer
  • 各メソッドの引数からaDragSessionが消えたので、Cc['@mozilla.org/widget/dragservice;1'].getService(Ci.nsIDragService).getCurrentSession();でその都度取得するようにした。
  • canDropの代わりの_setEffectAllowedForDataTransferは、返り値が真偽値ではなく文字列になっているので、それに合わせて色々変更。
  • 受け入れるデータ型の「text/unicode」が何故か「text/plain」に変わったので、他の箇所でも「text/plain」を受け入れるようにした+他の拡張機能でドラッグを開始する時に「text/plain」もセットするようにした。

ツリー型タブでは、Firefoxのtabbrowser要素の各メソッドを書き換える時に上記の点を動的に判別して、Firefox 3.0.xとFirefox 3.1の両方に対応するようにしている。

基本的に、新APIは旧APIの機能をほとんど包含しているので、旧APIに基づいて作った拡張機能等はほとんど機能を失うことなく新APIに移行できると思う。逆に、新APIではドラッグ元要素に新しいイベントが発行されるようになっているため、それをバリバリに使った新しい機能は旧APIベースで再現するのは大変そうだ。

これに関連してMDCの最初のページだけ訳してみたけど、新しいシステムの上で訳したのは初めてだったので、だいぶ難儀した。翻訳文書新規作成支援ボットは使えないし、リンク先はいちいち手で打ち直さないといけないし、リンク先を変える時に開くプロパティみたいな画面を表示する度にいちいちものすごく待たされるし……

Firefox 2.0.0.17とThnderbird 2.0.0.17のJavaScriptエンジンに極めて深刻な問題があるようです - Sep 30, 2008

仕事で書いてるコードがどーにもうまく動かなくて、ついこないだまで正常に動いてたのにどうして?!と思って色々試していたら、特定の関数をtoString()等で文字列化した時におかしな現象が起こっていた。具体的には、Thunderbird 2.0.0.17のAccountManager.jsで定義されているsaveAccount()を書き換えようとしたら例外が発生して、onSave()を文字列にしてreplace()で改変した物はfor〜inループだった箇所がwhileループになってしまっていた。コードを削っていったらめちゃめちゃ短いコードでも再現したので、Bugzillaに報告しておいた。

regression: Function.toString(), Function.toSource() and uneval() return wrong JavaScript code if the function includes "for ... in" roop

上記のような方法で動的にパッチを当てる手法を僕は多用してるので、仕事で書いたコードもここで公開してる拡張機能のコードも、正直、どのくらい影響を受けるのか見当も付かない。早急に解決されることを祈るのみだ。

ちなみにFirefox 3.0.3ではこの問題は起こらなかった。2.0.0.17で入ったセキュリティ上の修正による後退バグっぽい?

追記。29日時点ですでに修正済みだったようだ。これ、あと1ヶ月間放置ですか……? ものっそクリティカルなバグだと思うんだけど。

Mozilla Cross-ReferenceとMercurial - Aug 08, 2008

状況がよく分からなかったので改めて調べてみたことのまとめ。

Firefoxその他のMozilla製品のソースコードはこれまではCVSでバージョン管理されていて、MXR(Mozilla Cross-Reference)というサービスを使うと最新の内容をオンラインで検索できた。mozilla1.8(リンク先はMXR)を見ると、Firefox 2.0.0.xやThunderbird 2.0.0.xのコードを検索できる。

しかしCVSが使いにくいということで、Mercurialという別のバージョン管理システムに移行しようという話がずっと進んでいたそうで、Firefox 4を目指しているTrunkのリポジトリがmozilla-central(リンク先はMercurialのWebインターフェース)という名前でMercurial上に作成され、すでに自動ビルドも動いているという。

ちなみにMercurialがらみでよく「Hg」という単語が出てくるけれども、これは、水銀(mercury)の元素記号がHgだからだそうで、コマンドラインツールのコマンド名等も「hg」になってるんだそうな。知らんかった。

自分が把握できていなかったのは、以下の点。

  • CVSは完全に捨てて、全面的にMercurialに移行するのか? もう移行したのか? それとも、新しいプロジェクトやTrunkだけがMercurialに移行して、古いプロダクトは今後もCVSで管理されるのか?
  • MXRで検索できるのはCVSで管理されてた頃のコードだけなのか? だとしたらMXRに代わるツールはあるのか? それともMercurial移行後の物もMXRで検索できるのか?

結論としては、以下のことが分かった。

  • CVSは今も使われている。Firefox 2.0.0.xやThunderbird 2.0.0.xのコードはCVSのリポジトリにあり、今もコミットが続いている。
  • TrunkはCVSとMercurialの両方にリポジトリがあり、CVSの「trunk」がMercurialの「cvs-trunk-mirror」に自動的にミラーリングされているようだ。
  • mozilla-central(リンク先はMDCの解説)はFirefox 4(Mozilla 2)およびその先のバージョンのための新しいTrunkのリポジトリ。
  • MXRはCVS、Subversion、Mercurialのいずれにも対応している。Mercurial上にあるFirefox 4向けのコードはMXRのMozilla Centralのページから、将来のThunderbird向けのコードはMXRのComm. Centralのページから、CVSのFirefox 3系のコードはMXRのFirefox 3のページから検索できる。

以下、まだ分かってないこと。

  • Thunderbird 3のコードはどこを見るのが正解? Mercurialのcomm-central? それともCVSのmozilla? 将来的にはcomm-centralでいいんだろうけど、とりあえず今2008年8月8日現在ではどうなのか。
  • FirefoxのTrunkはCVSとMercurialのどっちを見るのが正解? CVSのmozilla? Mercurialのcvs-trunk-mirror? それともMercurialのmozilla-central? 将来的にはmozilla-centralでいいんだろうけど、とりあえず今2008年8月8日現在ではどうなのか。

Page 11/26: « 7 8 9 10 11 12 13 14 15 »

Powered by blosxom 2.0 + starter kit
Home

カテゴリ一覧

過去の記事

1999.2~2005.8

最近のコメント

最近のつぶやき