Home > Latest topics

Latest topics 近況報告

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

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

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

宣伝2。Firefox Hacks Rebooted発売中。本書の1/3を使って、再起動不要なアドオンの作り方のテクニックや非同期処理の効率のいい書き方などを解説しています。既刊のFirefox 3 Hacks拡張機能開発チュートリアルと併せてどうぞ。

Firefox Hacks Rebooted ―Mozillaテクノロジ徹底活用テクニック
浅井 智也 池田 譲治 小山田 昌史 五味渕 大賀 下田 洋志 寺田 真 松澤 太郎
オライリージャパン

Page 13/239: « 9 10 11 12 13 14 15 16 17 »

ツリー型タブの修正 - Aug 11, 2009

先週1週間は夏休み取って家に缶詰でずっともえじら組のマンガ描いてたんだけど、その間大量にバグ報告が来てたのをずっと見て見ぬふりしてたのを今週になってやっと修正した。

ブックマークフォルダの内容をタブで開けなくなるという問題はFirefox 3.0.xでのみ発生する問題で、原因はJavaScriptコードモジュールのPlacesUtilsにFirefox 3.5から追加された機能をそうとは知らずに使ってしまっていたせいだった。

あとブックマーク周りの変更が結構ボロボロだったのをだいぶ直した。特にスターアイコンのことは自分であんまり使わないからすっかり忘れてて、直すのに難儀した。Firefox自身がeditBookmarkOverlay.xulを動的に読み込んでいて、そのeditBookmarkOverlay.xulに対してツリー型タブがオーバーレイを適用しているために問題が……とか、とてもバッドノウハウくさい。結局、XULオーバーレイでどうこうするのは諦めてJavaScriptで動的にDOM要素を生成して挿入することにした。

var range = document.createRange();
range.selectNodeContents(container);
range.collapse(false);
range.insertNode(range.createContextualFragment(<![CDATA[
   <row align="center" id="treestyletab-parent-row">
      <label id="treestyletab-parent-label"
         control="treestyletab-parent-menulist"/>
      <menulist id="treestyletab-parent-menulist"
         flex="1"
         oncommand="TreeStyleTabBookmarksServiceEditable.onParentChange();">
         <menupopup id="treestyletab-parent-popup">
            <menuseparator id="treestyletab-parent-blank-item-separator"/>
            <menuitem id="treestyletab-parent-blank-item"
               value=""/>
         </menupopup>
      </menulist>
   </row>
]]>.toString().replace(/^\s*|\s*$/g, '').replace(/>\s+</g, '><')));
range.detach();

こんな感じにしておけば、XULの「タグを書くだけでUIを作れる」という利点をそれほど殺さなくても済む……と思う。E4XのXMLオブジェクトを生成した物を既存のDOMツリーに直接組み込むことができれば話は早いんだけど、そういうことは無理っぽいので、createContextualFragment()にしてる。ここではE4XのCDATAマーク区間をヒアドキュメント代わりに使ってるんだけど、文字列置換でタグの間の空白文字を消してるのと、toString()をわざわざ書いていることに注意が必要。前者を忘れると要素ノードの間にいちいちテキストノードが生成されてややこしいことになるし、後者をを忘れるとStringクラスの物ではなくXMLオブジェクト自身の方のreplace()メソッドが呼ばれてしまって文字列置換にならないので。

修正ついでに、ブックマーク項目の「親のタブ」を設定する機能について、もうちょっと自由に使えるように手を入れてみた。ツリー構造を書き換えるのと同時に、ツリーとして表示される時の順番に合わせてブックマークを自動的に並べ替えるようにした。

ツリー型タブでブックマークにツリー構造を保存できるようにしてみた - Jul 31, 2009

ツリー型タブ 0.8.2009073101/02で、「このツリーをブックマーク」や「すべてタブをブックマーク」した時に、ツリーの構造を含めてブックマークを保存するようにしてみた。だいぶ前から要望を受けてて、「確かにそうするべきだよなあ」とは思ってたんだけど、どうやって実現すればいいかで悩んでた。でもFirefox 2のサポートを切ったことによって、API経由でPlacesデータベースに色んな情報を簡単に保存できるようになったので、思い切って実装してみた。

他のアドオンからもこの機能を使えるように、APIを用意してある。複数のタブからブックマークを作成する場合、以下のように、PlacesUIUtils.showMinimalAddMultiBookmarkUI()でブックマークの追加を行う前後にツリー型タブのAPIを呼んでやると、タブのツリー構造がブックマークに保存される。

var tabs = Array.slice(gBrowser.mTabContainer.childNodes);

var isTSTBookmarksTreeStructureAvailable = (
        'TreeStyleTabBookmarksService' in window &&
        'beginAddBookmarksFromTabs' in TreeStyleTabBookmarksService &&
        'endAddBookmarksFromTabs' in TreeStyleTabBookmarksService
    );
if (isTSTBookmarksTreeStructureAvailable)
    TreeStyleTabBookmarksService.beginAddBookmarksFromTabs(tabs);
try {
    PlacesUIUtils.showMinimalAddMultiBookmarkUI(tabs.map(function(aTab) { return aTab.linkedBrowser.currentURI; }));
}
catch(e) {
}
if (isTSTBookmarksTreeStructureAvailable)
    TreeStyleTabBookmarksService.endAddBookmarksFromTabs();

このAPIはマルチプルタブハンドラでもさっそく使ってる。

やってることはどういう事かというと……

  1. まずTreeStyleTabBookmarksService.beginAddBookmarksFromTabs()の方では、ブックマークされる予定のタブのツリー構造をシリアライズして内部に保持した上で、ブックマークの監視を開始する。
  2. 次に、PlacesUIUtils.showMinimalAddMultiBookmarkUI()で複数のブックマーク項目が新たに作成される。この時、TreeStyleTabBookmarksServiceはブックマークの追加を監視していて、新しく作られたブックマークのIDを内部に保持する。
  3. 最後に、TreeStyleTabBookmarksService.endAddBookmarksFromTabs()の中で、追加されたブックマークと元になったタブとを対応させ、ツリー構造の情報(親のタブにあたるブックマーク項目はどれか、という情報)を、ブックマークのアノテーションとして保存する。この時、タブの数と作られたブックマークの数とが一致しない場合(ブックマークの追加がキャンセルされたとか、未知の機能によってタブと関係ないブックマークが同時に作成されたとか)は想定外のエラーということで、何もせず終了する。

とりあえず一番簡単なやり方で実装してみたので、保存した後のブックマークの順番や親子関係をいじくり回すとちょっと変なことになる。一応、そんなに大きな問題は起こらないで見た目上は何となく自然な形に収まるように、と工夫はしてみたんだけど……どうだろう。

保存された「どのタブが親か?」という情報は、ブックマークのプロパティから編集できるようにしてある。親を付け替えられるようにしてみたけど、横着してるのでちょっと制限が厳しい。そのうち、親を付け替えたらそれに応じてブックマーク項目自体の親フォルダ内での位置も自動的に入れ替えるようにでもしてみようかなー。

巻き戻し/早送りボタンが26日以降クラッシュする件 - Jul 27, 2009

巻き戻し/早送りボタンでSITEINFOを使うようにしてるとクラッシュする件。wedataから取得するデータの先頭の方をスキップするようにしたら落ちなくなったので、どうも正規表現が長すぎ(内部的に、すべてのSITEINFOのURLマッチング用の部分を繋げておいて「マッチするルールがあるか無いか」だけを調べるようにしてるんだけど、その正規表現が長すぎ?)なのが原因っぽい。wedataの更新履歴を見ると、この数日の間にもいくつかルールが追加されてるみたいだし。

で、とりあえず250件ごとに区切って正規表現を作るようにしてみたところ、手元の環境では落ちなくなったみたいなので、修正版として速攻で公開してみた。

しかし念のため全部のURLマッチング用の正規表現を繋げた正規表現を使ってテストしてみたところ、これだけではクラッシュしなかった。処理が走るタイミングにも依るんだろうか? これじゃいつまた問題が再発するか分からんよ……

ともあれ、今までの「でかい正規表現にマッチするかどうか判定」→「全部のSITEINFOをループで調べる」というのに比べると、250個単位で「正規表現にマッチするかどうか判定」→「その250個の範囲のSITEINFOをループで調べる」という風に変わったので、場合によっては多少高速になったんじゃないかなーと期待している。

参考までに、テストに使った巨大な正規表現は以下の通り。

続きを表示する ...

「個々のアドオンは単機能にしよう」は「複数のアドオンを簡単に一発で入れられる」と表裏一体だ - Jul 26, 2009

壱茉さんが久しぶりにFirefoxを使おうとして不便な思いをしていたらしい。

アドオン作者は自分のアドオンの担当領域をキッチリわきまえて、なるべく最小の物を作るようにして、他のアドオンとの互換性の確保に気をつけて欲しい、という風なことを僕は前から言ってるつもりで、それはある意味では、作者の人に過大なストレスから我が身を守って欲しいという提言のつもりでもあるんだけれども、ユーザの視点からは「導入までがめんどくさくなる」という話でもある。ユーザの導入時の負担を増やしてもイイからお前らは自分の身を守れ!というわけで、まあ、こういう事言ってりゃきっとエンドユーザからは嫌われるんだろうなあとも思う。

そのジレンマをある程度の所まで解消してくれるのが、僕が「コレクション」に期待していた機能であるところの、複数のアドオンをWebページ上から一発でインストールできる仕組みだと僕は思ってる。現状の「コレクション」でも単一のページから連続して複数のアドオンをインストールできるけれども、できればもっと簡単にして欲しかった。「全部インストールする」ボタンをクリックしたらそのコレクションに登録されてるアドオン全部が一緒くたになったメタパッケージがダウンロードされる、もしくはWebページのスクリプトによってそれらがまとめてインストールされる、という感じになっていて欲しかった。

これが実現されないことには、僕ら有志のアドオン作者はいつまで経っても、「あの機能も付けてくれ! この機能も!!」という要望に対していちいち「それはコンセプトと関係ない機能だから入れないよ」と断りの回答をするストレスから解放されない。また、そのストレスに耐えかねて・圧力に屈してホイホイ実装してしまえば、今度はそれが自分の首を絞める地獄へと繋がる

Mozilla Japanのアドオンライブラリではそれを独自にやろうとしてるということだけど、早いとこ実現して欲しいものだなあ。最初にそういう声が出てきてから、もう何年経つんだろう……

設定を簡単に変更できるようにすること、を必ずしも重視しませんよという話 - Jul 24, 2009

掲示板で書いた事を改めてここにもまとめてみる。

  • ツリー型タブの設定ダイアログを「ツール」メニューなどから簡単に呼び出せるようにして欲しい。
  • 閉じているサブツリー内の子タブがフォーカスされた時に、ツリーを展開するのではなく、現在見えている親のタブにフォーカスする、という風なオプションが欲しい。

この2つの要望にはどちらも応えるつもりはない、というよりも、安直に応えてはいけない種類の要望だと思ってる。

あらかじめ言っておくと、過去の「タブブラウザ拡張」ではこのどちらも応えていた。いや、要望に応えたと言うよりは多分、自分から進んでそうしてしまっていた。でも今の自分の考えでは、そうするべきではなかったと考えている。なので、もうしない。

そもそもを言えば、こういう要望が出てきてしまっているということが「失敗」の何よりの証拠だと僕は考えている。「何故、そういう要望が出るのか?」「どうしてそうして欲しいと思うのか?」そこを考えないといけないと思う。

  • 設定ダイアログを簡単に開けるようにしたいのは何故?
    • →設定を頻繁に変えたいから。
    • →設定を頻繁に変えないと使い物にならないから。
    • →だったら、設定を頻繁に変えなくても十分に使いやすいと感じられるように、自動判別の部分や初期設定をよく考えた方が、ユーザはハッピーになれるんじゃないの?
  • 閉じているサブツリー内の子タブにフォーカスが移った時に、そのタブが含まれているツリーを自動展開するのではなく、閉じられていない親タブに代わりにフォーカスして欲しい、と思うのは何故?
    • →本当は閉じられたツリーの中のタブではなく、親のタブの方にフォーカスして欲しかったから。
    • →というか、そのタブ(閉じられたツリーの中のタブ)がフォーカスされるなんて思いもしてなかったから、そうなってビックリした。
    • →使っていて自然と頭の中に思い浮かべるようになった「こう動くはずだ」という予想が裏切られてしまった。
    • →そのように想像させる挙動を他の部分がしているのなら、その想像に合った挙動をするように統一するべきなんじゃないの? 無駄に選択の余地を増やすんじゃなくて、「自然と思った通りに動いてくれる」状態を目指すべきなんじゃないの?

前者の要望は、色んなアドオンがそういう項目を「ツール」メニューにどんどん加えていったらメニューが一杯になってしまう!ということを見過ごしている。絶対に、多分別の人が「ツールメニューの中の項目は使わないので、非表示にするオプションを加えて欲しい」って言ってくるだろう。そしたらまたそれに応えるの?

後者の要望は、タブの一覧のリストやサムネイル一覧などからそのタブを選んだという風な、「本当にそのタブにフォーカスしたかった場合」にはどうすればいいのか?ということを考慮に入れずに安直に対応すると、泥沼に嵌ってしまう。不用意にそのオプションをいじってしまった人が「フォーカスしたいタブにフォーカスしてくれない!」と(自分がそう設定したからだと言う事にも気づかず)「バグ報告」してくるだろうし、それにまた安直に応えて「じゃあ、そういうケースだけは特別に、閉じられたツリーの中のタブにもフォーカスできるようにしよう」なんて後手後手の対応を続けていたら、どこまでいってもきりがない。

そういう安直な対応を繰り返した果てにあるのが、かつてのタブブラウザ拡張であり、今のTab Mix Plusであると、僕は考えてる。「多機能で凄い、良い物だ」と人は言うけれども、今の僕にはこれらは「考えることを放棄し続けた結果、肥大化の一途を辿った末路だ」という風に見えてる。既にツリー型タブもそうなりつつあると僕は思ってるので、今後は「設定項目を減らしていく」方向にシフトしたいくらいだ。

アプリケーションを作る立場の人は、要望として口に出された言葉の裏にある本当のニーズを読み取る努力をしておかないと、最終的には自分で自分の首を絞めることになると思う。「その方が格好よさそう」とか「その方が賢そう」とかのあまり意味のない自己満足なこだわりだろ、という風に切り捨てないで、自分自身の身を守るための現実的な対策のひとつとして、実践してほしいなと思う。

そしてその結果、それをエンドユーザとして使う立場に僕がなった時に、またハッピーになれるわけだ。

つまり「情けは人のためならず」とか「自業自得」とかそういう話。

現在のタブを閉じた後のフォーカス移動を制御するオプション(A new option to control focus of tabs when the current tab is closed is required.) - Jul 22, 2009

Q

I wonder if you consider integrating Tab Mix Plus into Tree Style Tabs? Not all of Tab Mix Plus but just the opening/closing/focus behavior (under "events" options of Tab Mix Plus)?

There is a lot of interaction between Tree Style Tabs and Tab Mix Plus. Some things don't work correct because Tab Mix Plus is very slow to update. For example, "duplicate tab" used to work in firefox 3.0, but in 3.5 it doesn't work right and Tab Mix Plus had not fixed it (the error is that the duplicate tab gets stuck in middle of tree).

Also Tab Mix Plus doesn't have enough options to give good control over Tree Style Tabs. So maybe it's better if Tree Style Tabs has own options.

Could you copy Tab Mix Plus code for opening/closing/focus, then add some new options for Tree Style Tab? For example:

  • If close first child tab, focus: up/down
  • If close middle child tab, focus: up/down
  • If close last child tab, focus: up/down
  • If close only child tab, focus: up/down
  • If close sub-parent tab, focus: up/first-child/last-child
  • If close expanded root-parent tab, focus: tab-above/parent-tab-above/first-child-down/last-child-down/

Tab Mix Plusをツリー型タブに統合するつもりはないでしょうか? TMPの全機能でなくとも、単にタブを開く・閉じる・フォーカス関係の挙動(TMPの設定の「イベント」パネルにある機能)だけでもいいんですが。

ツリー型タブとTMPの間には互換性がありますが、TMPの更新が非常に遅いため、いくつかの機能は正常に機能しません。例えば、「タブの複製」はFirefox 3.0では動いていましたが、Firefox 3.5では正常に機能せず、TMPはまだその問題を解決できていません(複製されたタブがツリーの真ん中に現れてしまうという問題があります)。

また、TMPはツリー型タブの挙動を制御するのに十分な数の設定項目を備えていません。ツリー型タブ自体がそのような設定項目を備えることが望ましいのではないでしょうか。

タブを開く・閉じる・フォーカス関係のTMPのコードをコピーして、ツリー型タブに新しい設定項目を加えてもらえないでしょうか? 例えば……

  • 最初の子タブを閉じた時:上にフォーカス/下にフォーカス
  • 真ん中の子タブを閉じた時:上にフォーカス/下にフォーカス
  • 最後の子タブを閉じた時:上にフォーカス/下にフォーカス
  • 最後の子タブを閉じた時:上にフォーカス/下にフォーカス
  • 他のタブの子である親タブを閉じた時:上にフォーカス/最初の子にフォーカス/最後の子にフォーカス
  • ツリーが展開されている最上位の親タブを閉じた時:上にフォーカス/親にフォーカス/最初の子にフォーカス/最後の子にフォーカス
A

Thank you for interesting idea. To be honest, I received some similar suggestions about tab focus of Tree Style Tab. However, I couldn't agree them because I hope to keep Tree Style Tab as simple as possible.

There are three reasons why I implemented only minimal options about tab focus.

  1. "Focus last selected" behavior is available with other existing addons.
  2. "Focus to upper (left) tab" hebavior was made obsolete by an old bugfix of Mozilla.
  3. Options dialog will become too complex.

1) Very special behavior, "focus to last selected tab when the current tab is closed" is available with known tiny addon, "Focus Last Selected Tab". So I'm recommending people to use the addon with TST. (BTW, Focus Last Selected Tab 0.9.x doesn't work with TST correctly, so I'll update TST as soon.)

2) For other cases, I don't agree to add "focus to upper (left) tab" option, because it was the default behavior of old Mozilla and it was "fixed" by usability reason. See bug 123563.

3) As you know, too many options for detailed cases will confuse people including me. So I have to make effort to reduce checkboxes, radiobuttons, and so on. Then, TST already have options to customize behavior of re-structuring tree after the current "parent" tab. I'm using the choice "raise the first child up to the new parent", but people can use others. How to unify options for two features, re-structuring and focusing? I cannot imagine to do it in the small dialog...

Anyway, this is only my policy, not the best answer. If people really want options for the feature, I hope that TST is extended by other developers like Tab Mix Plus born from Tab Mix.

興味深い意見をありがとうございます。正直に言うと、この手の提案は他にもたくさん受けています。しかし、私はツリー型タブを可能な限りシンプルに保ちたいので、これらの提案には同意できません。

タブのフォーカスに関して最小限の設定項目だけしか設けていないのには、以下の3つの理由があります。

  1. 「現在のタブを閉じた時、最後に選択されていたタブにフォーカスする」という挙動は、他の既存のアドオンで実現できる。
  2. 「現在のタブを閉じた時、上(左)のタブにフォーカスする」という挙動は、Mozillaの過去のバグ修正によって廃止された物である。
  3. 設定ダイアログが非常に複雑になってしまう。

1) 「現在のタブを閉じた時に、最後に選択されていたタブにフォーカスする」という非常に特殊な挙動は、既存のよく知られたアドオンFocus Last Selected Tabで実現できます。なので私は、それとツリー型タブを使うことをお勧めしています。(ちなみに、Focus Last Selected Tab 0.9.xはツリー型タブと組み合わせると期待通りには動きません。この点についてはなるべく早くツリー型タブを更新するつもりです。)

2) それ以外の挙動について、私は「現在のタブを閉じた時に、上(左)のタブにフォーカスする」という設定項目を設けることには同意しません。なぜなら、その挙動は古いMozillaの既定の挙動であったものの、利便性の観点から「(問題であるという認識の上で)修正された」からです。詳しくはbug 123563を見て下さい。

3) 言うまでもなく、詳細な場合ごとの過剰な数の設定項目は、私を含めてユーザを混乱させます。なので私は、チェックボックスやラジオボタンなどの数を減らす努力をしないといけません。ツリー型タブはすでに、親タブを閉じた後のツリーの再構築についての設定項目を備えています。私は「最初の子を新しい親にする」という選択肢を使っていますが、他の人は別の選択肢を使っているかもしれません。これら2つの機能(親タブを閉じた時のツリーの再構築と、現在のタブを閉じた時のフォーカスの移動)の設定項目をどのように統合すればいいでしょうか? 私には、それを小さなダイアログの中でやってのける様子が想像できません。

ともかく、これはあくまで私のポリシーであって、最良の答えというわけではありません。もしみんなが本当にその機能のための設定項目を必要としているのなら、Tab MixからTab Mix Plusが生まれたように、他の開発者の人がツリー型タブをさらに拡張してくれることに、私は期待します。

英語でどう書けばいいのか分からなかったんでこういう書き方になったけど、ぶっちゃけ、「カスタマイズのためのチェックボックスやドロップダウンリストは多ければ多いほどいい」という発想には反吐が出る。そういうことは隠し設定で十分だろ、と。about:configでやりゃいいだろ、と。何でもかんでもダイアログの中に詰め込むという発想は、僕がかつて取り憑かれそして我が身を滅ぼすに至った忌むべき考え方だ、と僕は認識している。

マルチプルタブハンドラでタブのURIをコピーする時のフォーマットをカスタマイズできるようにした - Jul 20, 2009

マルチプルタブハンドラではタブを選択した後に「すべてのURIをコピー」で選択したタブのURIをコピーすることができて、その時の形式を「URIだけ」「タイトルとURI」「HTMLのリンク」の3種類から選べるようになってたんだけど、今回のバージョンアップで、ここにさらにユーザが好みの形式を追加できるようにしてみた。ついでにマイナーバージョンも1つ上げてみた。

プレースホルダにはCopy URL +と同じものを利用できる(ツールチップの説明には書いてないけど%LOCAL_TIME%%UTC_TIME%も使える)。自分は以下のものを追加して使ってる。

HTML Link List
<li><a href="%URL_HTMLIFIED%">%TITLE_HTMLIFIED%</a></li>
Markdown
[%TITLE_HTMLIFIED%](%URL_HTMLIFIED% "%TITLE_HTMLIFIED%")
Markdown (list)
 * [%TITLE_HTMLIFIED%](%URL_HTMLIFIED% "%TITLE_HTMLIFIED%")
RD
((<%TITLE_HTMLIFIED%|URL:%URL_HTMLIFIED%>))
RD (list)
 * ((<%TITLE_HTMLIFIED%|URL:%URL_HTMLIFIED%>))
Retrospectiva
[[%TITLE_HTMLIFIED%|%URL_HTMLIFIED%]]
Retrospectiva (list)
* [[%TITLE_HTMLIFIED%|%URL_HTMLIFIED%]]

Weave - Jul 17, 2009

WeaveはFirefox 3.0じゃ動かないからってことでわりかしスルーしてたけど、Firefox 3.5正式版が公開されて自宅のWindows Vistaと会社のWindows Vistaのメイン環境が両方ともFirefox 3.5になったんだからってことで、改めて入れ直してみた。

おー、確かに同期されてる。

  • 家でしか見てないはずのサイトがスマートロケーションバーの検索に引っかかるようになる。
  • 同じく、家マシンのFirefoxで開いてたタブを、会社マシンでメニューから開くことができる。開いたタブはセッションヒストリまで含めて複製されている。→ツリー型タブのツリー構造も含めて複製できるように改良してみたい。
  • 「よく見るページ」とかのクエリ項目が重複した状態になるのはちょっといただけない……片方削除すればいいんだけどさ。

フォームの入力履歴やパスワードマネージャの内容も同期されてるはずだけど、実感できるケースにまだ遭遇してない。

デフォルトではMozillaが提供してるサーバに情報を保存するようになってるけど、サーバ側のソースセットアップ手順も公開されてるので、心配なら自分でサーバ立てることもできるようだ。機械があればチャレンジしてみたい。

nsIZipWriterを使ってFirefoxでZIPアーカイブを作る - Jul 16, 2009

nsIZipWriterを使えばアドオンでZIPアーカイブを作れるということを割と最近になってやっと知ったので、アドオンのXPIへのパッケージングまで全部アドオンでできるやん!と思ったんだけど、使い方がよく分からんかったので、実験と練習もかねてコンテキストメニュー拡張の短縮構文で使える汎用的な処理を書いてみた。

要点だけ抜き出すとこんな感じ。

// aSources = nsIFileの配列
// aZipFile = 作るZIPアーカイブのnsIFile
// aCompressionLevel = 圧縮率(0で無圧縮、9で最大圧縮、デフォルトは6)
zipFilesAs : function(aSources, aZipFile, aCompressionLevel) 
{
    // Firefox 3以降じゃないと動かないよ!
    if (!('nsIZipWriter' in Components.interfaces))
        throw Components.results.NS_ERROR_NOT_IMPLEMENTED;

    if (!aSources || !aSources.length || !aZipFile) return;

    if (aZipFile.exists() && !this.isZipFile(aZipFile))
        aZipFile.remove(true);

    const PR_RDWR        = 0x04;
    const PR_CREATE_FILE = 0x08;
    const PR_APPEND      = 0x10;
    const PR_TRUNCATE    = 0x20;

    var writer = Components
                    .classes['@mozilla.org/zipwriter;1']
                    .createInstance(Components.interfaces.nsIZipWriter);

    if (aCompressionLevel === void(0))
        aCompressionLevel = writer.COMPRESSION_DEFAULT;

    // 新規ZIPアーカイブと既存のZIPアーカイブではフラグが違う
    var flags = aZipFile.exists() ?
                    PR_RDWR | PR_APPEND :
                    PR_RDWR | PR_CREATE_FILE | PR_TRUNCATE ;
    writer.open(aZipFile, flags);

    aSources.forEach(function(aFile) {
        var entry = this+aFile.leafName;
        // フォルダに対応するエントリの有無を調べる時は、
        // エントリ名の末尾に「/」が必要
        var entryForCheck = aFile.isDirectory() ? entry+'/' : entry ;

        // すでにあるエントリで、フォルダではない物は削除。
        // (フォルダを削除しないのは、内容をマージするため)
        if (!aFile.isDirectory() && writer.hasEntry(entryForCheck))
            writer.removeEntry(entry, false);

        // 新しいエントリを追加
        if (!writer.hasEntry(entryForCheck))
            writer.addEntryFile(entry, aCompressionLevel, aFile, false);

        if (aFile.isDirectory()) {
            var files = aFile.directoryEntries;
            while (files.hasMoreElements())
            {
                arguments.callee.call(
                    entry+'/',
                    files.getNext().QueryInterface(Components.interfaces.nsILocalFile)
                );
            }
        }
    }, '');

    writer.close();
},

// ファイルの内容を実際にZIPアーカイブとして読んでみて、ZIPアーカイブかどうか調べる
isZipFile : function(aFile)
{
    var isZip = false;

    if (!aFile || !aFile.exists()) return isZip;

    var reader = Components
                    .classes['@mozilla.org/libjar/zip-reader;1']
                    .createInstance(Components.interfaces.nsIZipReader);
    try {
        reader.open(aFile);
        try {
            var entries = reader.findEntries('*');
            while (entries.hasMore())
            {
                entries.getNext();
                isZip = true;
                break;
            }
            if (!isZip) {
                entries = reader.findEntries('*/');
                while (entries.hasMore())
                {
                    entries.getNext();
                    isZip = true;
                    break;
                }
            }
        }
        catch(e) {
        }
        reader.close();
    }
    catch(e) {
    }

    return isZip;
},

Reload Tab On Double-Clickとマルチプルタブハンドラおよびその他のアドオン、テーマとの競合の問題 - Jul 16, 2009

マルチプルタブハンドラが入ってるとReload Tab On Double-Clickが機能しなくなるという問題について調べてみた。

調べた限りでは、この問題はマルチプルタブハンドラに限らず、タブのバインディングがデフォルトの物から変更されていると起こりうる物のようだ。マルチプルタブハンドラと同じバインディングを使うツリー型タブ情報化タブもそうだし、バインディングを使ってスライスされた画像を貼り付けているサードパーティ製テーマでも起こりうる。

Reload Tab On Double-Clickの「ダブルクリックがタブの中で行われたかどうか」の判定箇所で、「イベントが発行された元々のノードまたはその親がタブかどうか」しか確認されていないためにこの問題が起こっているので、ここをいじって「イベントが発行された元々のノードの祖先にタブがあるかどうか」を見るようにすれば、問題は解決される。例えば以下のような感じ。

e.originalTarget.ownerDocument.evaluate(
  'ancestor-or-self::*[local-name()="tab"]',
  e.originalTarget,
  null,
  XPathResult.BOOLEAN_TYPE,
  null
).booleanValue

ということで作者のkyoさんに連絡はしておいた。後はどうなるかシラネ!

Page 13/239: « 9 10 11 12 13 14 15 16 17 »

Powered by blosxom 2.0 + starter kit
Home

カテゴリ一覧

過去の記事

1999.2~2005.8

最近のつぶやき

オススメ

Mozilla Firefox ブラウザ無料ダウンロード