Home > Latest topics

Latest topics 近況報告

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

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

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

Page 9/248: « 5 6 7 8 9 10 11 12 13 »

Minefield 4.0b2preではどうも同期的な処理がことごとく失敗するようになっている気がする - Jul 06, 2010

XUL/MigemoのMinefield 4.0b2pre対応のために色々検証していて、1つとても困った問題にぶち当たった。rangefindを使ってWebページ中の要素を装飾する時に、前から後ろに向かって処理を行うと検索が止まってしまう。

Components.utils.import('resource://gre/modules/debug.js'); 
const Cc = Components.classes;
const Ci = Components.interfaces;

function decorate() {
  var span = d.createElement('span');
  span.setAttribute('style','font-size:150%;');
  foundRange.surroundContents(span);
}

/* コンテンツ領域にテスト用の内容をロードする */
var d = Cc['@mozilla.org/appshell/window-mediator;1']
          .getService(Ci.nsIWindowMediator)
          .getMostRecentWindow('navigator:browser')
          .content.document;
d.documentElement.innerHTML = 'Firefox, Firefox, Firefox.';
d.documentElement.clientTop; /* ←伏線 */

/* rangefindを初期化する */
var find = Cc['@mozilla.org/embedcomp/rangefind;1'].createInstance(Ci.nsIFind);
find.findBackwards = false; /* 前から後ろに向かって検索 */
find.caseSensitive = false;

var findRange= d.createRange(); /* 検索する範囲 */
findRange.selectNodeContents(d.documentElement);
var startPoint = findRange.cloneRange(); /* 検索の始点 */
startPoint.collapse(true);
var endPoint = findRange.cloneRange(); /* 検索の終点 */
endPoint.collapse(false);

/* 検索を実行 */
var term = 'Firefox';
var foundRange = find.Find(term, findRange, startPoint, endPoint);
NS_ASSERT(foundRange !== null, '1回目で失敗');

decorate(); /* DOMツリーを編集して装飾する */

/* 検索の範囲を変える(編集した箇所より後を検索の範囲にする)*/
findRange.setStart(foundRange.endContainer, foundRange.endOffset);
startPoint.setEnd(foundRange.endContainer, foundRange.endOffset);
startPoint.collapse(false);

/* もう一度検索を実行 */
foundRange = find.Find(term, findRange, startPoint, endPoint);
NS_ASSERT(foundRange !== null, '2回目で失敗');

decorate(); /* DOMツリーを編集して装飾する */

エラーコンソールにこれをコピペして実行してみると、2回目の方で必ず失敗してしまう事が分かる。本当は「Firefox」という文字列が2箇所装飾されて欲しいのに、最初の1箇所だけで処理が止まってしまう。

これ、上のサンプルの中で伏線と書いている部分が鍵なんだけど、どうもこういうことらしい。

  • DOMツリーを編集すると、編集した箇所から先の範囲が「不確定」な状態になる。
  • 「不確定」な範囲に対しては、rangefindは一切の検索を行えない。
  • DOM要素のプロパティにアクセスするなどしてレイアウト情報を参照すると、状態が強制的に「確定」される。
  • または、setTimeout()等で少し遅らせて処理を行えば、その時には状態が「確定」されている。
  • 状態が「確定」されると、その範囲をまた検索できるようになる(最初の方にある d.documentElement.clientTop は、実はそのための物)。

1回目の検索結果のRangeの箇所でDOMツリーを切った貼ったしているので、その箇所より後の部分はどう頑張ってもそのままの流れでは検索できないようになってしまっている、ということのようだ。

なので、

  • 2回目以降の検索を実行する前に span.clientTop あたりにアクセスしてやれば(これ以外にもclientLeftでもoffsetWidthでもレイアウト系のプロパティなら何でもいいっぽい)、whileforのループを回し続ける事ができる。
  • 毎回setTimeout()で状態の「確定」を待ってやるというやり方でもよい。

という風な回避策があると言える。でも、後者は言わずもがな、前者も毎回レイアウト情報を参照するからクソ重くなりそうで、できればどっちの方法もとりたくない所だ。

将来的にどうなるのかは知らんけど、とりあえず今のところは、後方検索(Rangeの後ろの方から前の方に向かって検索する)ならこの問題に引っかからずに済むみたい。編集した箇所から先の部分が「不確定」になっても、後方検索だと「編集した箇所から先=もう検索が終わった範囲」なので。(→と思ってたけどやっぱり動作が怪しいので安全めな方に倒すということで毎回clientTopにアクセスする方法を使う事にした。なんか負けた気分。)

この「rangefindでループを回してDOMツリーを切った貼ったして装飾する」というやり方はFirefox 2以前のページ内検索における「すべて強調表示」の実装方法だったんだけど、今のFirefoxではDOMツリーはいじらずに強調箇所を選択範囲として処理するようになってて、この問題は問題にならないようだ。今でもFirefox本体でこういうことをやってるところがあれば「これってregressionなんじゃないの」とbugzillaに報告できるところだと思うんだけど……

Firefoxのバージョン間の差異を吸収するライブラリをこそ、僕は欲しているというのに。 - Jul 03, 2010

Firefox 3.6以前とMinefieldとでは、アドオンマネージャのAPIがまるっきり変わってしまった。

Firefox 3.6以前のアドオンマネージャ(Cc['@mozilla.org/extensions/manager;1'].getService(Ci.nsIExtensionManager))は同期的なAPIで、頑張ってラップすればvar enabled = isEnabled('treestyletab@piro.sakura.ne.jp');みたいな感じで「その場で結果を取得する」ことができた。でも今のMinefield(アドオンマネージャがタブで開かれるようになった奴)では、インストール済みのアドオンの情報を取得しようと思ったら必ずコールバック関数を使った非同期なAPIでやらなきゃいけないようになってしまった。

// このコードはMinefield(Firefox 4)以降でないと動かない
Components.utils.import('resource://gre/modules/AddonManager.jsm');
AddonManager.getAddonByID(
  'treestyletab@piro.sakura.ne.jp',
  function(aAddon) {
    if (aAddon && aAddon.isActive) {
      // ツリー型タブがインストール済みで、
      // 且つ有効化されている時の処理
    }
    else {
      // ツリー型タブが利用できない時の処理
    }
})

Firefox 3.6以前と今のMinefield(つまり将来のFirefox 4)の両方に対応しようと思うと、この差異をどうやって吸収するかがネックになる。そこで、メインスレッドの処理を一時停止して処理の完了を待つ裏技を使って、同期的なやり方で他のアドオンの有効・無効の状態を調べたり設定ダイアログを開いたりするためのライブラリをMinefieldでもそのまま使えるようにしてみた。

// このライブラリを使うと、Firefox 3.6でもMinefieldでも
// 違いを意識しないでコードを書けるようになる。
var extensions = window['piro.sakura.ne.jp'].extensions;
if (extensions.isAvailable('treestyletab@piro.sakura.ne.jp')) {
  // ツリー型タブが利用できる時の処理
}
else {
  // ツリー型タブが利用できない時の処理
}

そしたら、Minefieldで起動時にセッションが復元されないという現象に遭遇してしまった。条件を絞り込んでいくと、どうもアドオンマネージャのタブが開かれた状態のセッションが復元される時に問題が起こっていて、さらに辿っていくと、上記の裏技で新アドオンマネージャの処理を止めていると、アドオンマネージャのタブの読み込みが阻害されてしまってセッション復元が半端な所で止まってしまうという事のようだった。

仕方がないので、Firefox 3.6以前のやり方に合わせるのではなく今のMinefieldのやり方に合わせる方向でestensions.jsのAPIを拡張して、今後はそっちの使い方を推奨する事にした。

// 新しい書き方。これも、Firefox 3.6でもMinefieldでも
// 違いを意識しないでコードを書いて大丈夫。
var extensions = window['piro.sakura.ne.jp'].extensions;
extensions.isAvailable('treestyletab@piro.sakura.ne.jp', {
  ok : function() { /* ツリー型タブが利用できる時の処理 */ },
  ng : function() { /* ツリー型タブが利用できない時の処理 */ }
});

Firefox 3.6以前でこのAPIを呼んだ場合は、非同期にならずにその場でコールバック関数が呼ばれるという実装上の違いがあるけれども、基本的に非同期で実行される前提でコードを書いておきさえすれば、Firefox 3.6以前でもMinefieldでもそのまま動くようになってる。コールバック関数を渡さなければ今まで通りの同期的なAPIとして動作するので、コールバック関数はどーしても使いたくない!という場合は、非推奨ではあるけど今まで通りの使い方もできる。

FUELとかJavaScriptコードモジュールとか、Firefox本体の方で色々ユーティリティっぽい物が用意されつつあるけど、僕の立場(複数のバージョンのFirefoxをサポートしたいという前提がある)では、それらはまるっきり役に立たない。新しいバージョンのFirefoxで標準のコードモジュールが増えた所で、現行のリリース版のFirefoxにも対応させるなら、結局それは使えないのだから。しかも、Firefoxのバージョンが上がったらAPIが使えなくなっちゃいましたなんて事もザラにある(今回の話も、nsIExtensionManagerがゴッソリなくなってしまったせいで起こった問題だ)。

そういう「簡単に書けますよ」っていうだけのAPIは、もう、ぶっちゃけどうでもいい。そんな物より、Firefoxの複数のバージョン間での差異を吸収するライブラリこそが僕には必要なんだ。新しいやり方に合わせて書いておけば古いバージョンのFirefoxでもそのまま使える、というのでも、古いやり方のままで新しいバージョンのFirefoxでも動く、というのでも、どっちでもいいんだけど、とにかく1つの記述でどっちのバージョンでも動くようにしておきたい。そうじゃないと、新しいFirefox用と古いFirefox用とで目的が重複するコードがどんどん増えていって、片方は直したけどもう片方は直し忘れてたみたいな穴がどんどん増えていって、すぐ破綻してしまう。

FUELはFirefoxのバージョン間の違いを意識しないで使えるようなAPIの提供を目指してたはずだと思ってたけど、今となってはその計画も頓挫してすっかりうち捨てられてしまったような印象がある。実際、今回の件についてもFUELのAPIは互換性を失う形であっさり変更されてしまってて、もうFirefox 3.6の物と同じ使い方はできないし、Firefox 3.6の物の使い方もMinefieldではできない。JetpackはRebootで明後日の方向に飛んで行ってしまって、少なくとも「Firefox 4から先」の事しか眼中になくてFirefox 3.x系はガン無視っぽい。結局、Mozilla本家はアテにならない。アドオン作者が自分達でやる以外にない。

そういう理由で作ったライブラリ類をリポジトリの中にまとめて置いてあるので、似たような事を考えてる人は覗いてみるといいかもしれない。JavaScriptコードモジュールとして使える物はmodestのJavaScriptコードモジュールの紹介ページに簡単な紹介を書いておいたけど、どれもソースの頭の方に用例を付けてあるので、まあ見てもらえばだいたい分かるんじゃないかな。

一応、簡単な説明。

  • jstimer.jsm:JavaScriptコードモジュール等のDOMWindowを参照しづらい場面でsetTimeout()とかsetInterval()とか書けるようにするライブラリ。
  • namespace.jsm:JavaScriptコードモジュール同士で名前空間を共有できるようにするライブラリ。同じJavaScriptコードモジュールの同じ内容のファイルを複数のアドオンでそれぞれ別々に持たせて、それぞれのメモリ空間も別々に確保される、というのがものすごくあほらしく思えたので作ってみた。
  • animationManager.js:JavaScriptでアニメーションさせる時に、複数アドオンで1つのタイマーを使い回して効率よくアニメーションさせるためのライブラリ。jstimer.jsmと併用すればJavaScriptコードモジュールとしても使える。
  • arrowScrollBoxScrollHelper.js:arrowscrollboxの中に1つ大きなボックスが入っていてその中に小さなボックスがたくさんある、という場面でarrowscrollboxのスクロール処理がぶっ壊れる問題を回避するライブラリ。
  • autoScroll.js:mousemoveまたはdragoverイベントに基づいてタブバーの自動スクロールを行うライブラリ。
  • bookmarkMultipleTabs.xul / bookmarkMultipleTabs_bookmarkPropertiesOverlay.xul:複数のタブをまとめて1つのブックマークフォルダにブックマークするためのライブラリ。Firefox本体の機能だと「全部のタブを保存」しかできないので。
  • boxObject.js:HTMLDocumentのgetBoxObjectFor()を使ってたコードを、手直しせずにそのままFirefox 3.5とかで動くようにするためのライブラリ。
  • extensibleToolbarButton.css / extensibleToolbarButton.xml / extensibleToolbarButton.xul:Firefox本体のツールバーボタンに後からappendChild()とかで内容を追加できるようにするためのライブラリ。
  • extensions.js:このエントリでメインの話題にしてる、「他のアドオンがインストールされているかどうかを調べる」「他のアドオンの設定ダイアログを開く」といった事を簡単に行えるようにするライブラリ。
  • operationHistory.js:何かの操作をアンドゥ・リドゥできるようにしたいときのための汎用的な履歴管理ライブラリ。詳しくは解説のエントリを参照してください。
  • prefs.js:FUEL/STEELが無いような古いバージョンも対象にする場合向けの、簡単に設定を読み書きできるようにするライブラリ。
  • stopRendering.js:ウィンドウ内の再描画を一旦止めて、その間に色々GUIをいじくる処理をして、最後にまとめて表示に反映させる、という事をやるためのライブラリ。画面がチラついてなんか気持ち悪い、という不快感を和らげるのが目的。Firefox 3.6以前とMinefieldとでは実装が中身の自動的に切り替わるけど、APIとしてはFirefoxのバージョンの違いを意識せずに使えるようになってる。
  • stringBundle.js:stringbundle要素をXULの方に埋め込まなくても、同じAPIでpropertiesファイルの中の文字列を読めるようにするAPI。
  • tabFx2Compatible.css / tabFx2Compatible.xml / tabFx2Compatible.xul:Firefox 3以降でtabbrowserのtabの中にappendChild()とかで要素を追加できるようにするためのライブラリ。Firefox 2以前のDOMツリー構造を再現して、中にいくつかのボックスを増やす。
  • UninstallationListener.js:アドオンのアンインストールが行われたタイミングで、変更した設定を自動的に元に戻すとかの後片付け的な処理をやるためのライブラリ。Minefieldでは多分動かなくなってる気がするので、後で直しときます。

初期化処理を書く時に注意がいるようになったみたい - Jul 03, 2010

ツリー型タブが入ってるとMinefield 4.0b2preがぶっ壊れる現象に遭遇した。

何が原因なのかちょっとずつ絞り込んでいったところ、DOMContentLoadedイベントが発火するよりも前の時点で<tabbrowser id="content"/>に触っていたのが原因ぽいという事が分かった。ツリー型タブの初期化処理の中でtabbrowser要素の属性値を取ろうとしてdocument.getElementById('content').getAttribute('...')としただけで、XBLのconstructorとかそのへんがぶっ壊れて、tabbrowser要素の初期化処理が全く行われない状態になってしまってたようだ。

ツリー型タブのインストール後にツールバーのカスタマイズ内容が失われるという話も、これが原因だったんだろうか? 状況としてはよく似てるんだけど。

この問題の発生を避けるには、初期化処理を必ずDOMContentLoadedイベントかloadイベントのタイミング以降で行うようにするのが多分一番簡単だと思う。

window.addEventListener('load', function() {
  window.removeEventListener('load', arguments.callee, false);
  // 何か初期化処理
}, false);

他にも、複数バージョンに対応したアドオンでバージョン判別のために'MozBorderImage' in element.styleとかやってる場合も危険かもしれない。とにかく、DOM要素(の属性値であるとかDOMオブジェクトのプロパティであるとか)を参照せずにメタ的な情報(XPCOMで取得できるGeckoのバージョン情報とかnsIPrefBranchで取得できる設定値とか)で判断できる場合はなるべくそっちを使った方が安全っぽい。例えばFirefox 3.5以降かどうかを調べるならこんな感じ。

var comperator = Cc['@mozilla.org/xpcom/version-comparator;1']
                   .getService(Ci.nsIVersionComparator);
var XULAppInfo = Cc['@mozilla.org/xre/app-info;1']
                   .getService(Ci.nsIXULAppInfo);
if (comparator.compare(XULAppInfo.version, '3.5') >= 0) {
  // Firefox 3.5.0およびそれ以降
}
else {
  // Firefox 3.0およびそれ以前
}

pinTab()、unpinTab()への対応 - Jun 27, 2010

このへんのパッチが投入されて、gBrowser.pinTab()gBrowser.unpinTab()というメソッドが実装された。 (実際に使った所のスクリーンショット) pinTab()にタブを渡すとそのタブが他のタブの左側に寄せられて、unpinTab()に(pinnedな)タブを渡すと元に戻る。ぶっちゃけアレですね、Chromeの似たような機能のパクリですね。

この時、タブはスクロールボタン(左向き三角のボタン)よりもさらに左に表示されるようになるんだけど、これは一体どうやって実現されてるのか。実は、CSSで非常にトリッキーなことをしている。pinTab()に渡されたタブはpinnedという属性の値にvalueが設定されるんだけど、この時、.tabbrowser-tab[pinned="true"]なタブはposition:fixedに設定されて、通常の描画フローから切り離される。その上で、スクロールボックスの左にすべてのpinnedなタブの幅の合計と同じだけのマージンを設けて、pinnedなタブ1つ1つにはネガティブマージンを設定してそれらしい位置に表示する……という感じ。moveTab()の中とかでタブの状態を見て処理を分けていて、pinnedなタブはpinnedじゃないタブの中には移動できないし、その逆も然り。原稿のコードに対する最小限の変更でそれらしい挙動を実現するようにしている。よう思いつくな、こんなの。

大抵の既存のアドオンは影響を受けないはずなんだけど、タブ周りで凝ったことをしてる奴は、下手したら全滅しそうな気がする。というかツリー型タブなんかはお話にならないのが目に見えてる。なのでちょっと頑張ってみた。

  • pinnedなタブのレイアウトの処理。改行とか。
  • pinnedになった時、自動的にツリーから解放するとか。

結果。 (スクリーンショット) 最初は単に、pinnedなタブのレイアウト処理の所のX軸とY軸を入れ換えるだけにしてみたんだけど、それだと縦置きタブバーの場合は無駄な領域がメチャメチャ増えるだけだという事が分かったから、「タブが小さくなる」という所を優先して、24×24固定サイズでアイコンを並べられるだけ並べる(1行に収まらなければ改行する)という風にした。見た目は……あんまり良くないね。すんません。

縦置きしたタブバーとpinnedなタブの相性はすこぶる悪い。結局全部ツリー型タブの方で作り直すのに近い状態になってしまった気がする。でもまあ挙動としてはそれなりに違和感のない状態に落ち着いた。

これからまた実装に仕様変更が入らないことを祈るばかりだ。実装の仕方自体が変わってしまうなら、今回のこの作業はまるっきり無駄になってしまうから。

タブバーの位置を変える方法(How to change the position of the tab bar easily?) - Jun 15, 2010

Q

It is nice if I can switch between tabs on the top and side. I know you can drag it but if the top gets filled up, then its hard to drag it. Then I have to open the prefs to move it. Be nice if it was easier to move the tab bar to different sides quickly.

タブバーの位置を上と左(または右)の間で簡単に切り替えられると便利だと思います。タブバーをドラッグすれば場所を移動できるのは知っていますが、タブバーが上にありタブが沢山開かれていて余白がない場合、タブバーをドラッグするのは難しいです。そういう時は仕方がないので設定ダイアログを使うほかありません。タブバーを異なる位置に簡単に移動できる方法があるといいのですが……

A

I have no plan about (re-)adding the feature to the Tree Style Tab. I think an answer for another question possibly help you: A new option to switch the position of the tab bar by the number of tabs.

By the way, you can start to drag the tab bar without blank spaces in the tab bar. Try to drag something in the tab bar not a tab. (ex. "New Tab" button, "<" button, ">" button, or "List All Tabs" button)

その機能を(再び)ツリー型タブに加える予定はありません。ただ、他の質問に対する回答があなたにとって何らかの助けになるかもしれません。タブバーの縦置き・横置きをタブの数に応じて自動で切り替えたいを参照して下さい。

それはさておき、タブバーのドラッグ&ドロップは、タブバーに余白が無くても行う事ができます。タブバーの中のタブ以外の任意の位置(例えば「新しいタブ」ボタン、スクロールボタン、「タブの一覧」ボタンなど)をドラッグしてみて下さい。

新しいタブを開く時にタブバーの下の端以外の位置に開きたい(How to open new tab not on the bottom of the tab bar?) - Jun 15, 2010

Q

If I open a new tab they always open on bottom. I have alway many tabs open and I need to scroll always down to see new tab. That's for me not very comfortable. Is possible that new tab open on top?

新しいタブを開く時、タブは常にタブバーの一番下に開かれます。私はいつも非常に多くのタブを開いているため、開いた新しいタブを見るためにはいつも一番下までタブバーをスクロールしないといけません。これは非常に面倒です。新しいタブをタブバーの上の端に開く方法はありませんか?

A

Now TST doesn't provide such a feature to control new tab position. I think TST should not implement features not related to "tree of tabs", but it should be done by another addon designed for the purpose, for example, Tab Control does it.

現在、ツリー型タブはそのための機能を提供していません。私は、「タブのツリー」とは関係ない機能はツリー型タブには含めず、そういう目的のために開発された他のアドオンで解決するべきと考えています。例えばTab Controlがそういう機能を持っています。

「xpcnativewrappers=no」の廃止 - Jun 09, 2010

レガシーな仕組みが1つ廃止されたようだ。

XPCNativeWrapperについては過去に行った拡張機能のセキュリティに関するプレゼンの中でも紹介した。現在も既に、chrome権限があるコードからWebページの内容に触る時は基本的には必ずXPCNativeWrapperを介してアクセスしないといけないようになってるんだけど、そういう仕組みがまだ入ってなかった頃の書き方でも拡張機能を書けるように、敢えてこの仕組みをOFFにするための機能があった。それがchrome.manifestでのxpcnativewrappers=no指定。今回上記のbugで投入されたパッチによって、この指定がそもそも機能しないようになった。

XPCNativeWrapper越しでなく生のJavaScriptのオブジェクトにアクセスする方法としては、xpcnativewrappers=no以外にもう1つ、任意のオブジェクトの.wrappedJSObjectというプロパティを見る方法がある。今回投入されたパッチではこの機能までは削除されていないように見えるので、今までxpcnativewrappers=noを使っていた人は、Webページ内のJavaScriptのオブジェクトにアクセスしてた箇所では.wrappedJSObjectを書き加えるようにすれば一応は動くようになるんじゃないかと思う。セキュリティ的には、そもそもラップされてない生のJSObjectに触らなきゃいけないという設計自体を変えた方がいいんだけど。だいたい、XPCNativeWrapperが入ったのってFirefox 1.5がリリースされるよりも前の話だよ。今なおXPCNativeWrapperの存在を前提にしてないコードって、どんだけ古いのさ?

タブのコンテキストメニューが正常に機能しなくなった? (The context menu on tabs doesn't appear anymore?) - May 15, 2010

Q

I'm running your Tree Style Tab extension on the last Firefox, 3.4a. I installed the Menu Editor extension and the context menu on the tabs stopped to appear. Until Firefox 3.6.3 they were working together nicely.

私はツリー型タブを最新版のFirefox(3.7a4)で使っています。Menu Editorをインストールしていると、タブのコンテキストメニューが出なくなってしまいました。Firefox 3.6では両者は正常に機能していたのですが……

A

Codes of the context menu on tabs are totally restructured on the Firefox 3.7a4. See: Bug 554991 - allow tab context menu to be modified by normal XUL overlays. So, addons including codes about context menu on tabs must be updated.

TST newer than 0.10.2010040201 has been updated for the change, but I couldn't find out a version updated for Firefox 3.7a4 from all versions of the Menu Editor.

If the problem still appear with a new version of the Menu Editor updated for Minefield 3.7a4 and later, please tell me again.

タブのコンテキストメニューの実装は、Firefox 3.7a4で大きく変わりました。Bug 554991 - allow tab context menu to be modified by normal XUL overlays を参照してください。このため、タブのコンテキストメニューを触るアドオンは更新されなくてはなりません。

ツリー型タブのバージョン0.10.2010040201以降はこの変更に対応済みですが、私はMenu Editorの公開済みのバージョン一覧からMinefield 3.7a4に対応したバージョンを見つけることはできませんでした。.

もしMenu EditorのFirefox 3.7a4対応版がリリースされた後でもまだ問題が再現するようであれば、改めてご連絡ください。

一言でいえば、「Firefox 3.7a4の新仕様にきちんと対応してないアドオンと組み合わせて何が起こっても僕の責任じゃないですよ」ってことで。

「タブを閉じる」ボタンの働きの選択肢として「親のタブを閉じずに子孫のタブだけを閉じる」が欲しい(A new option to close only child tabs by "Close Tab" button) - May 14, 2010

Q

My small suggestion is to be able to configure the close button for a parent tab to just close its children. After it is child-less, the second click would close the tab itself. My feeling is that this would make for more fluid experience when you open up a flurry of child tabs to follow up on details and want to continue with the main "story" or "task" on the original parent tab. As it is now you have to right click and select close children, which I find a bit clunky.

私の希望は、親のタブの「タブを閉じる」ボタンをクリックした時の挙動として、子孫のタブだけを閉じるというオプションが欲しいというものです。そのタブに子供がいなくなった後、2度目のクリックはそのタブ自身を閉じるでしょう。これがどういうときに役立つかというと、何か作業をしている時に、詳細な情報を見るために子タブをいくつか開いた後で、それらを一気に閉じて元の作業に戻るという風な場合です。現状でこのような使い方をするには、タブを右クリックして「このタブの子タブをすべて閉じる」を選択しなくてはならないので、面倒です。

A

Sorry, I have no plan to implement the feature to Tree Style Tab. There are two reasons: 1) overriding of the behavior of "close tab" button is hard to implement. And, 2) I think it is not an instinctive behavior.

1) Now there are some options for "close tab" of parent tabs, but all options are designed to work just after the parent tab was correctly closed. Because, TST listens "TabClose" event which is fired after the tab is completely closed by Firefox itself. We cannot cancel the closing of the parent tab from "TabClose" event.

2) If "close tab" button closes the tab and its collapsed children, I think it is instinctive, because it is same to the default behavior of the "close tab" button, except there are collapsed (hidden) children. And if the button closes only the parent tab (keeping children open) it is also same to the Firefox default. "When the close button is clicked, only children are closed and the tab itself is still there" -- the scenario is odd a little for me.

However, you can implement the feature with other scriptable addons (FireGestures, userChrome.js, etc.) with following codes:

var parentTab = gBrowser.selectedTab;
if (TreeStyleTab.hasChildTabs(parentTab)
  // The second argument "true" means "close only children".
  TreeStyleTabService.removeTabSubtree(parentTab, true);
else
  gBrowser.removeTab(parentTab);

すみませんが、その機能をツリー型タブ本体に取り込むつもりはありません。それには2つの理由があります。1) 「タブを閉じる」ボタンの挙動を乗っ取るのは実装が大変ですし、2) その挙動は直感的とは私には思えません。

1) 現在、親のタブの「タブを閉じる」ボタンをクリックした場合の挙動にはいくつかの選択肢を設けてありますが、そのいずれも、親のタブ自体が閉じられた後に働くことを前提にしています。これはツリー型タブが、タブが完全に閉じられた後でFirefox自身によって発行される「TabClose」イベントを監視することによってこの機能を実現しているためです。「TabClose」イベントからは、タブを閉じる操作自体をキャンセルする事はできません。

2) 「タブを閉じる」ボタンによってそのタブ自身とすべての折り畳まれた子タブが閉じられる場合、そこに折り畳まれた(見えない)子タブがあるという点を除けばFirefoxの標準的な挙動と同じなので、これは私には直感的な挙動に感じられます。また、もしそのタブだけが閉じられて子タブが残るのであれば、これはFirefoxの標準的な挙動と全く同じです。しかしながら、「タブを閉じるボタンをクリックしたら、子タブだけが閉じられて、そのタブは已然として開かれたままとなる」――この挙動は、私には違和感があります。

とはいえ、あなたはこの機能を、スクリプトでカスタマイズする機能を持った他のアドオン(FireGestures、userChrome.jsなど)と組み合わせる事で実現できます。上記のコードを参照して下さい。

Page 9/248: « 5 6 7 8 9 10 11 12 13 »

Powered by blosxom 2.0 + starter kit
Home

カテゴリ一覧

過去の記事

1999.2~2005.8

最近のコメント

最近のつぶやき