Home > Latest topics

Latest topics 近況報告

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

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

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

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

再起動のいらないアドオンのコンテストが11月8日頃〆切で行われているそうですね - Nov 01, 2011

Firefoxアドオンコンテストの要項を意訳してみた。 - おんがえしの日記で報じられていますが、「再起動のいらないアドオン」というテーマでアドオンのコンテストが開かれているそうです。

再起動のいらないアドオンというとAdd-on SDKを使って開発すればそういう風になる訳ですが、何度か勉強会等で話している通り、再起動のいらないアドオンを作るだけならSDKなしでも作る事は可能です。そういう物も応募できるのか? という質問がやはり告知のページにも寄せられていて、回答としては、「SDKなしでもいいよ」と書いてありました。なので、老害のくせに性懲りもなく応募してみる事にしました。

まずFox Splitter

URL
https://addons.mozilla.org/firefox/addon/fox-splitter/
Name
Fox Splitter
Description

Do you want to browse multiple webpages (ex. "English version" and "translated version") side by side? This can do it.

This provides ability to "split" a Firefox window to multiple ones, and manages them (grouped windows) like a large window with multiple panes. To "split" the window, "Split" button in the navigation toolbar is available. Otherwise, you just have to drag a tab to near the inner edge of the window itself, and stay there. Then a drop position marker will appear like the screenshot: https://static-cdn.addons.mozilla.net/img/uploads/previews/full/59/59710.png?modified=1309171529 Not only two panes, but also three, four, or more "panes" are available. Of course, when you resize a member window, others also fit to it like panes in a large window.

This is developed without Add-on SDK but based on my tiny framework named "Restartless", including customizable toolbar items, configuration dialogs, l10n, Firefox 3.6 support, and so on. https://github.com/piroor/restartless

あと、Back to Owner Tab

URL
https://addons.mozilla.org/firefox/addon/back-to-owner-tab/
Name
Back to Owner Tab
Description

Have you met such a stressful situation?: You finished to read a webpage and want to back to the previous page, but you can't click the "back" button because it is disabled - yes, you were in a new tab opened from the previous page, so you have to close the current tab instead of clicking "back" button.

This provides ability to go back/forward across tabs/windows. Even if the current page is in the first (or last) entry in the history, the "back" (or "forward") button is still enabled. If you click the button, then the owner tab (or the "next" tab - it had focus before the "owner") gets focus.

This is developed without Add-on SDK but based on my tiny framework named "Restartless", including customizable toolbar items, configuration dialogs, l10n, Firefox 3.6 support, and so on. https://github.com/piroor/restartless

最後にさらに宣伝しておくと、先日発売されたオライリーのFirefox Hacks Rebootedには、GomitaさんによるAdd-on SDKを使ったアドオン開発のチュートリアルと、Add-on SDKを使わない再起動不要なアドオン開発での色々なテクニック・注意点のまとめの両方が収録されています。再起動不要なアドオンには興味があるけど、まとまった情報が無くて二の足を踏んでる……という方がもしいらっしゃいましたら、こちらの本を片手に挑戦してみるといいかもしれませんね。

Back to Owner Tab(親のタブに戻る)を「進む」に対応させた - Aug 30, 2011

親のタブに戻るで使ってる再起動不要なアドオンのテンプレートそのものに「無効化した状態でアップデートしたら勝手に有効になってしまう」という重大な不具合があったので、その更新も兼ねて、「進む」方向への対応を加えて肉リリースした(太平洋標準時)。

前のバージョンでは単純にタブの.ownerを見て戻る先を判断してたんだけど、これはタブのフォーカスが切り替わるとクリアされてしまうので、1回親のタブに戻ったらそれっきりだった。また、.ownerがクリアされてしまっては、「進む」がクリックされた時にどこに「進」めばいいか分からないし、仮に分かったとしても現在のタブから複数の子タブが開かれていた場合はどこに「進」むのが妥当かという判断がつかない。ということで、「進む」への対応はしてなかった。でも実際使ってたらうっかり「戻」ってしまった後にまた「進」みたくなるという場面が結構あったので、いずれは何とかしたいなーとは思ってた。

で、肉リリース目指してせっかくだから片付けとこうと思って手を付け始めたら、これが結構大がかりな事になってしまって、結局、タブ毎に固有のIDがあって、各タブが自分の親のタブの情報を常に持っていて、ついでに自分が最後にフォーカスされた時刻も持っている、というファットな実装になってしまった(ツリー型タブの初期のバージョンと同じくらいの情報を持ってることになる)。

それでどうなったかというと、前までは1回しか「親のタブに戻る」できなかったのが、何階層でも祖先のタブに「戻」って、その後また元見ていたタブまで「進」む、という事ができるようになった。タブの垣根を越えて透過的に「戻る」「進む」できるというのはかなり変な気分だ。横置きの普通のタブバーでやると、自分が今どのタブを見てるかわかんなくなるんじゃないだろうか。そういうわけで、これはツリー型タブとの併用をお薦めしておきたい(ツリー型タブとの併用時ならツリー構造として既に構築済みの親子関係をそのまま「戻る」「進む」に使えるというメリットもあるのです)。

Bootstrapped Extensionsで設定ダイアログを提供するためのライブラリを作ったよ - Jan 28, 2011

Firefox Developers Conference 2010の時に再起動不要なアドオンの作り方を調べた時、調査の成果を元にJetpack SDKもといAdd-on SDKを使わずにFirefox 3.6とMinefieldの両方に対応したBootstrapped Extensionを作るためのテンプレを作った。それ以後、新しく作るアドオンでBootstrapped Extensionにできそうな物はなるべくそのように開発していこうと思ってて、Back to Owner Tabは実際そうして作ったアドオンの第1号ということになる。

SDKの使い方や仕組みを調べた時にもちょっと思ったんだけど、Back to Owner Tabを作って、「設定ダイアログを持てないのがこんなに辛いとは……」ということを改めて感じた。しかしBootstrapped Extensionで設定ダイアログを提供するのは簡単には実現できなさそうだったので、ずっと諦めてた。

今回、うまく解決できそうな方法をふと思いついて、実際試してみたら案外うまくいったので、テンプレの一部としてライブラリ化してみたBack to Owner Tabの設定ダイアログもこれで提供してる

Bootstrapped Extensionで設定ダイアログを提供するのは難しい

Firefox 2以降ではXULにprefwindowというウィジェットが存在していて、これはFirefox自体の設定ダイアログにも使われている物で、非常に出来がよい。今ある拡張機能の多くも、これを使って設定ダイアログを提供している。

prefwindowができるまでは「設定値を保持して、変更を監視して、変更があったらUIに反映して、ダイアログがキャンセルされたら変更を破棄して……」てな事をいちいち考えてゼロから設定UIを設計しなきゃいけなかったから、非常に辛かった。そういう思いがあるので、Bootstrapped Extensionでも是非これを使いたかったんだけど、Bootstrapped Extensionの「Chrome URLを登録できない」という制限のせいで無理だった。

  • prefwindowも含めて、XULを使うにはChrome URLでFirefoxにファイルを読み込ませないといけない。
    • Minefieldではfile:やresource:で始まるURLでXULを読み込ませても表示されなくなった(リモートXULの廃止)。
  • 仮にXULファイルを読み込ませることができても、表示する文字列をローカライズできない。
    • XULでの多言語対応で欠かせないDTDファイルは、セキュリティの制限によりChrome URLに置かれた物(chrome://foobar/locale/foobar.dtdなど)しか読み込めない。
    • propertiesファイルから文字列を読み込んでJavaScriptで動的に埋め込むということは無理ではなさそうだけど、死ぬ程めんどくさい。XULの「タグで書くだけでいい」「静的なファイルに内容をまとめておける」という利点が完全に死ぬ。

どうしてもやりたければ、XUL以外の方法で頑張って設定UIを作るか、XULで物凄く苦労して作るしか無いってことになって、それはどっちも嫌だった。せっかくprefwindowという素晴らしい物が目の前にあるのに、それを使わないでオレオレUIをゼロから作るなんて、馬鹿馬鹿しくてやってられない。

せめて最新のSDKだったら設定ダイアログを作る機能が入ってたりしないだろうか? あるんならそれを丸パクリできないかな? と思ってたんだけど、SDKに設定ダイアログのためのAPIが入るのはまだ先のことらしいと聞いて、それも諦めざるを得なかった。

それで仕方なく「about:configでカスタマイズしてね」ということにしてたんだけど、まあ普通に考えてこれはエンドユーザ向けとしては酷い話なわけですよ。自分で使う時も、マウス操作だけで設定を変えられないのは困る。

解決の糸口

そんな風に悶々としていて、ふと、「そういえばuserChrome.jsとかではdata: URIでXULドキュメントを動的に作ってたよな」ということに思い至った。試しにdata: URIにprefwindowで作った設定ダイアログの内容を突っ込んでnsIWindowWatcherのopenWindow()でウィンドウとして開いてみたら、少なくともMinefield 4.0b11preでは正常に動いてくれた。data: URIでドキュメントを読み込んだりウィンドウを開いたりする時はオープン元のスクリプトの権限が引き継がれるっぽいので、file: URLでXULを読み込ませた時のような問題も起こらないようだ。

また、E4Xを使えばJavaScriptの中に直接XMLを書けて、しかも属性値にJavaScriptの変数を埋め込める。これなら、propertiesファイルベースでのローカライズでもラベル等を埋め込むのが苦にならない。で、そうして作ったE4XのXMLオブジェクトをtoXMLString()すれば、data: URIで読み込ませるダイアログのためのソースコードが得られる。

ということで、「XULのソースコードを文字列として受け取ってdata: URIにしてウィンドウを開く機能」と「アドオンマネージャでアドオンの設定を開くボタンが押下された時に前述の機能を呼び出す機能」を作れば、Bootstrapped Extensionでもprefwindowベースの設定ダイアログを提供できる事が分かった。

propertiesファイルでローカライズする

propertiesファイルの内容はローカライズ済みの文字列をXULのstringbundle要素を介して取得する方法が一般的だと思うけど、より低レベルな実装のnsIStringBundleServiceを直接呼べば、JavaScriptコードモジュールやBootstrapped Extensionの中からでもpropertiesファイルの中身を簡単に取り出せる。(stringbundle要素はXBLでそういう処理を行うようにしてあるに過ぎない。)

上記のテンプレには、nsIStringBundleServiceをラップしてstringbundle要素と同じインターフェースで使えるようにするライブラリを既に入れてある。

var bundle = require('path/to/lib/locale.js')
               .get('file://.../messages.properties');
var title = bundle.getString('config.title');

という風にすると、ブラウザのUIの言語がjaでmessages.properties.jaというファイルがあればそれが使われて、存在しない場合はmessages.properties.en-US→messages.properties(サフィックス無し)とフォールバックしていく。

Back to Owner Tabに入ってるバージョンのライブラリには含まれてないけど、テンプレのHEADでは resolve('path/to/file') とすると現在のファイルを起点にして相対パスを解決できるようにしてあので、こういう風にも書ける。

var bundle = require('path/to/lib/locale.js')
               .get(resolve('locale/messages.properties'));

なお、Bootstrapped Extensionの場合は読み込んだpropertiesファイルの内容がキャッシュされたままになってしまうとまずいので、shutdown()の時にはnsIStringBundleServiceのflushBundles()というメソッドを呼んで、メモリ上のキャッシュを消すようにする必要がある。このライブラリでもそうしてて、自分でnsIStringBundleServiceを使う時はここに気をつけないといけない。

E4Xで作ったXULコード片から動的にChromeウィンドウを開く

Bootstrapped ExtensionやJavaScriptコードモジュールの名前空間からで既存のDOMWindowを取れない状態でウィンドウを開きたい場合には、nsIWindowWatcherのopenWindow()を使う必要がある。このメソッドに渡すURIとしてdata: URIを指定すれば、その内容のウィンドウがChrome権限で開かれる。

var uri = 'data:application/vnd.mozilla.xul+xml,'
         + source;
Cc['@mozilla.org/embedcomp/window-watcher;1']
  .getService(Ci.nsIWindowWatcher)
  .openWindow(null, uri, '_blank',
              'chrome,titlebar,toolbar,centerscreen',
              null);

ソース文字列の生成は、E4Xを使うと楽にできる。

var xml = <>
      <prefwindow id="backtoowner-config"
                  xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
                  title={bundle.getString('title')}>
        <prefpane id="prefpane-general"
                  label={bundle.getString('general')}/>
      </prefwindow>
    </>;
var source = '<?xml version="1.0"?>'
             +'<?xml-stylesheet href="chrome://global/skin/"?>'
             +xml.toXMLString();
source = encodeURIComponent(source);

ラベル文字列等に日本語が入る場合を考慮して、ソース文字列はdata: URIに繋げる前にエスケープしておこう(これをしないと文字化けする)。

基本的にはこれでいいんだけど、実際このまま使うと何となく気持ち悪い。というのも、prefwindowは画面上でのウィンドウの位置や大きさ、最後に選択されていたパネルの名前等をプロファイル内のlocalstore.rdfに自動的に保存するんだけど、この時保存されるデータはウィンドウのURIをキーとして紐付けられているから、data: URIのウィンドウだとlocalstore.rdfが肥大化してしまう。しかも、設定項目を追加したりしてウィンドウの中身が変わるとdata: URIも変わるから、前回情報を保存した時のエントリとは別のエントリが作られてしまって、古いエントリは自動的には消えないから、localstore.rdfが際限なく膨らんでいってしまう事になる。長く使うことを考えたら、これはよくない。

で、何かいい方法はないか考えてみた。

  1. data: URIは必要最小限の長さの固定の物にして、document.write()でウィンドウの中身を動的に書き換える。
  2. data: URIは必要最小限の長さの固定の物にして、DOM操作でウィンドウの中身を動的に書き換える。

nsIWindowWatcherのopenWindow()は開かれたウィンドウのDOMWindowオブジェクトを返す。なので、こんな風にできないかと最初は考えた。

var window = ww.openWindow(...);
window.document
  .open('application/vnd.mozilla.xul+xml');
window.document.write(source);
window.document.close();

が、駄目だった。この方法でドキュメントを書き出すと強制的にHTMLのパーサーが使われてしまうらしく、XULのソースを書き出しても全く動作しない状態になってしまった。

次に、DOM操作でやることを考えた。

XUL Documentの中でRangeを作ってcreateContextualFragment()すると、XULのソース文字列からDOMDocumentFragmentを作ることができる。こうしてルート要素も含めたドキュメント全体を作り直してゴソッと入れ替えたらどうなるだろうか。

var window = ww.openWindow(...);
var range = window.document.createRange();
range.selectNode(window.document.documentElement);
var fragment = range.createContextualFragment(xml.toXMLString());
window.document.replaceChild(fragment, window.document.documentElement);

実際やってみたら、これは期待通りには動いてくれなかった。多分、開かれたウィンドウの内容がまだ完全には読み込まれ切っていない状態でDOM操作を外から無理矢理やろうとしたからなんだろうと思う。

開かれたウィンドウのDOMContentLoadedを待ってからDOMを操作すればprefwindowについてはちゃんと動くみたいなんだけど、dialogとかのもっと汎用的な物も受け付ける事や、ダイアログの中にDOMContentLoadedを待って処理を開始するようなコードを含めたい時に、それでは問題が起こる気がする。

そういうわけで今のバージョンでは、ウィンドウを開く時にnsIVariantの形でソース文字列を渡して、開かれた側のウィンドウの中に1つだけ置いたscript要素でarguments[0]を受け取ってすぐにドキュメントを書き換えるようにしてみている。要点だけ抜き出すとこんな感じ。

var variant = Cc['@mozilla.org/variant;1'].createInstance(Ci.nsIWritableVariant);
variant.setFromVariant(source);

ww.openWindow(
  null,
  'data:application/vnd.mozilla.xul+xml,'
  +encodeURIComponent(
   '<?xml version="1.0"?>\n'
   +'<!-- ' + aURI + ' -->\n'
   +'<?xml-stylesheet href="chrome://global/skin/"?>\n'
   +<window xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
      <script type="application/javascript"><![CDATA[
        var d = document;
        var e = d.documentElement;
        var r = d.createRange();
        r.selectNode(e);
        d.replaceChild(r.createContextualFragment(arguments[0]), e);
        r.detach();
      ]]></script>
    </window>.toXMLString()
  ),
  '_blank',
  'chrome,titlebar,toolbar,centerscreen',
  variant
);

URIをコメントで埋め込んでるのは、複数のアドオンでこのライブラリを使ってる時に衝突しないようにしたかったから。

実はここに辿り着くまでに結構紆余曲折があった。最初はルート要素を差し替えられるという事に気づいていなかったので、「ルート要素の属性値の情報」と「子孫要素のソース」をそれぞれ取り出してやってみていた。E4Xは実はよく分かってないからちょっと苦労した。

var content = xml.*.toXMLString(); // 子孫要素だけ抽出
var container = xml.copy(); // ルート要素だけ取り出すためにまず一旦全体を複製
var attributes = container[0].attributes(); // ルート要素の属性のリストを取得
var attributesHash = {};
for each (var attribute in attributes) { // 属性名と値のペアのハッシュにする
  let name = attribute.name();
  attributesHash[name] = attribute.toString(); // 属性値はtoString()で取れる
  delete container[0]['@'+name]; // removeAttribute()に相当する操作はこう書く
}
// 子孫要素を削除して、コンテンツ差し替え用のスクリプトに入れ換える
delete container.*;
container.script = <script type="application/javascript">{this._loader}</script>;
container = container.toXMLString();

最初はこれでいいかと思ってたんだけど、コンテンツ差し替え用のスクリプトが走ってる時点で既にprefwindowのXBLのコンストラクタが実行されてしまっていて、複数のprefpaneがあるときの切り替え機能が働いてなかった。

ルート要素をもう一度作りなおしてドキュメントに挿入すればXBLのコンストラクタが実行されるはず、ということでdocument.removeChild(document.documentElement);の後でdocument.appendChild(newRoot);みたいな風な事も試してみたけど、一瞬documentElementが無くなってしまうのがマズいようで、他のどっかの処理がルート要素を参照するタイミングとぶつかってエラーになってしまった。ここはdocument.replaceChild(newRoot, document.documentElement);で一気に差し替えてしまうのが正解だった。昔のGeckoはreplaceChild()でクラッシュする事があったような気がするので無意識に使用をずっと避けてきてたんだけど、Firefox 3.6以降ともなるとさすがに問題なく動いた。

あと、生成した新しいルート要素を挿入しようとするとエラーになる場合もあって、その時は挿入しようとしているノードをdocument.importNode()に1回通してやれば動いた。まあ最終的にはそれ無しで乗り切れたんだけど。

アドオンマネージャからアドオンの設定ダイアログを開こうとした時に、動的に生成したダイアログを開く処理を呼ぶ

これも難儀した。

Firefoxのアドオンマネージャは、install.rdfのoptionsURLに書かれてるURIをwindow.openDialog()で(Mac OS X以外では)モーダルダイアログとして開くようになっている。しかし前述の通りXULの設定ダイアログを読み込ませたかったらChrome URLにしないといけないので、これはそのままは使えない事になる。

とはいえ、optionsURLにはChrome URLしか使えないという話ではない。

最初は、ここに直接javascript:ダイアログを開くためのコードという感じのスクリプトを書く事を考えてみた。でもメタデータの置き場所であるinstall.rdfにそういう実装を含めるのはどうかと思うし、そもそもここにjavascript:スキームを使って書いたスクリプトは普通にコンテンツ領域の権限でしか実行されないようなので、nsIObserverServiceを使ってイベントを発行するとかそういう高度な事は全然できなかった(実際試して無理だった)。

次に、nsIWindowWatcherでの監視とかnsIObserverServiceを介して送られるchrome-document-global-createdとかcontent-document-global-createdとかの通知でもって「あらかじめ登録されていたURI」が読み込まれた事を検知して、その読み込み(ウィンドウのオープン処理)をキャンセルして別の設定ダイアログを開くという事を考えた。

これは結構イイ線まで行ったんだけど、「Firefoxのアドオンマネージャが開いたウィンドウ」が一瞬だけ見えてしまうという点をどうしても回避できなかった。openDialog()の実装を辿ってnsGlobalWindow::OpenDialog()nsGlobalWindow::OpenInternal()nsWindowWatcher::OpenWindowJS()nsWindowWatcher::OpenWindowJSInternal()と掘り返して、何か抜け道はないか探しまくったんだけど、内部で新しいDOMWindowが生成されてウィンドウが実際に画面に出現する事がほとんど確定した後で初めてnsIDocShellのloadURI()にURIが渡されてる(この間URI文字列はC++の普通の変数で引き回されてるだけでJavaScriptの層からは触りようがない)みたいで、ウィンドウがユーザの目に触れる前にどうこうってのは原理的に無理っぽい。

いや、nsIContentPolicyインターフェースを備えたXPCOMコンポーネントを作ってカテゴリマネージャに登録すれば、もしかしたらそこに割り込む事はなんとかできるかもしれない。けど、設定ダイアログ1つ開くためだけにそこまでする元気はなかったし、求める機能に対してコードが膨大になりすぎるから普通にこれはないわーって感じだしで、そういう方向性は最初から切り捨ててる。

結局、すべてのドキュメントの読み込みをchrome-document-global-createdとcontent-document-global-createdの通知で捕捉して、アドオンマネージャのウィンドウが開かれた時にはボタンのクリック操作を監視するイベントリスナを登録し、「設定」ボタンをユーザがクリックした瞬間を捕捉して、登録済みのURIだったらイベントをキャンセルして別のダイアログを開く、という所に落ち着いた。これだとアドオンマネージャの実装(現在どのアドオンが選択されているのか、そのアドオンの設定ダイアログのURIは何なのか、を取得する方法)にべったりになってしまわざるを得ないんだけど、まあその辺のレイヤだったら変更があっても追随するのはそう大変じゃなかろうと思って、妥協する事にした。

まとめ

冒頭に書いたけど、ここまでのまとめがBootstrapped Extensionsテンプレートライブラリとして入ってる。他のファイルの内容に可能な限り依存しないように作ったつもりなので、改造再利用も不可能ではないと思う。実際にどう使うのかというのはBack to Owner Tabでの利用例が参考になるかもしれない(って単にE4XでダイアログをJavaScriptのコードの中に埋め込んでるだけだけど)。

ほんとはFirefox 4に向けて記事を書いていかなきゃいけないんだけど、こういう「あれも駄目でした、これも駄目でした、結局こういう所に落ち着かざるを得ませんでした」という紆余曲折は本に入れてもウケないんじゃないかなーって思ったので、ここに書く事にした。また次に同じような事をしようと思った時に同じ轍を踏まなくてもいいように。技術情報のドキュメントは、未来の自分のために残しておく物なのです。

新しいタブとかウィンドウとかで「戻る」を押しても戻れねえよムキーッとなる問題を解消するアドオン「親のタブに戻る(Back to Owner Tab)」をリリースしたよ - Jan 07, 2011

Back to Owner Tabというアドオンを作ってみた。

例えば初心者ユーザにはこういう事がありがちだろう。

  • ブラウザのウィンドウを常に最大化して使っている。
  • タブとかウィンドウとかよく分かってない。「戻る」ボタンを押せば1つ前のページに戻れる、という事は(教わったので)知っている。
  • リンクをクリックした結果新しいページが表示されたとして、それがただのページ遷移なのか、新しいタブで開かれたのか、新しいウィンドウで開かれたのか、違いがよく分かってない。
  • 新しいウィンドウで開かれたページを見終わって「元のページに戻ろう」と思って「戻る」ボタンをクリックするが、ボタンをクリックしても何も起こらない。

こういう場面で、「戻る」をクリックしたらとにかく元のタブなりウィンドウなりに戻るようにするのが、このアドオンだ。

だいたい、ウィンドウを最大化してたりタブを表示しないようにしてたりすると、「戻る」で戻れるのかそうでないのかすぐには分からないから、初心者でなくてもこういう物には意味があると思う。

Firefox 3.5以降では browser.tabs.selectOwnerOnClose が true で且つそのタブが「新しいフォアグラウンドのタブ」として開かれた時にだけ「このタブの親はこのタブですよ」という情報が保持される。また、JavaScriptではwindow.openerでオープン元のウィンドウを辿ることができる。このアドオンは、これらの情報を手がかりにして「親のタブ」を検索するようになってる(ツリー型タブがあるならツリーの構造から親のタブを検出する)。

確かタブブラウザ拡張にもこういう機能を含めてた気がするんだけど、それらを単機能の拡張機能として再実装した時に取りこぼしてた。その後、ツリー型タブにこの機能を含めてくれという要望が何回か来てたんだけど、今だったら browser.tabs.selectOwnerOnClose があるから別にツリー型タブに依存した機能にしなくてもいいよなーと思ったので、こうして今回新たに1つのアドオンとして作ってみたというわけ。

Add-on SDKは使ってないけどBootstrapped Extensionsの形にしてあるので、Minefieldでは再起動無しでインストールできる。昨年の発表では「Bootstrapped Extensionsでは『戻る』ボタンの挙動をオーバーライドするみたいな事はできない」と言ったけど、やってみたらできてしまった。あと、そのために使った方法がFirefox 3.6では動作しなくてちょっと悩んだんだけど、Firefox 3.6ではそもそも絶対に再起動が必要だから「変化を可逆的にする」事にこだわらなくてもいいので、そこは横着してダーティなやり方を使ってる。

なんとなく既出のような気もしたけど、「back owner」とかその辺の単語で検索してもそういう物を見つけられなかったので、じゃあ作るか……と思って作ってみた。既出だったら恥ずかしい。

ちなみに、似たような目的のアドオンでTab Historyという物もある。こちらは「新しいタブを開く時に、元のタブの『戻る』『進む』の履歴を引き継ぐようにする」というアプローチを取っている。僕もTab Historyを使ってたんだけど、せっかく作ったので、しばらくはBack to Owner Tabを使って様子を見てみようと思ってる。

新しいタブとかウィンドウとかで「戻る」を押しても戻れねえよムキーッとなる問題を解消するアドオン「親のタブに戻る(Back to Owner Tab)」をリリースしたよ - Jan 01, 1970

Back to Owner Tabというアドオンを作ってみた。

例えば初心者ユーザにはこういう事がありがちだろう。

  • ブラウザのウィンドウを常に最大化して使っている。
  • タブとかウィンドウとかよく分かってない。「戻る」ボタンを押せば1つ前のページに戻れる、という事は(教わったので)知っている。
  • リンクをクリックした結果新しいページが表示されたとして、それがただのページ遷移なのか、新しいタブで開かれたのか、新しいウィンドウで開かれたのか、違いがよく分かってない。
  • 新しいウィンドウで開かれたページを見終わって「元のページに戻ろう」と思って「戻る」ボタンをクリックするが、ボタンをクリックしても何も起こらない。

こういう場面で、「戻る」をクリックしたらとにかく元のタブなりウィンドウなりに戻るようにするのが、このアドオンだ。

だいたい、ウィンドウを最大化してたりタブを表示しないようにしてたりすると、「戻る」で戻れるのかそうでないのかすぐには分からないから、初心者でなくてもこういう物には意味があると思う。

Firefox 3.5以降では browser.tabs.selectOwnerOnClose が true で且つそのタブが「新しいフォアグラウンドのタブ」として開かれた時にだけ「このタブの親はこのタブですよ」という情報が保持される。また、JavaScriptではwindow.openerでオープン元のウィンドウを辿ることができる。このアドオンは、これらの情報を手がかりにして「親のタブ」を検索するようになってる(ツリー型タブがあるならツリーの構造から親のタブを検出する)。

確かタブブラウザ拡張にもこういう機能を含めてた気がするんだけど、それらを単機能の拡張機能として再実装した時に取りこぼしてた。その後、ツリー型タブにこの機能を含めてくれという要望が何回か来てたんだけど、今だったら browser.tabs.selectOwnerOnClose があるから別にツリー型タブに依存した機能にしなくてもいいよなーと思ったので、こうして今回新たに1つのアドオンとして作ってみたというわけ。

Add-on SDKは使ってないけどBootstrapped Extensionsの形にしてあるので、Minefieldでは再起動無しでインストールできる。昨年の発表では「Bootstrapped Extensionsでは『戻る』ボタンの挙動をオーバーライドするみたいな事はできない」と言ったけど、やってみたらできてしまった。あと、そのために使った方法がFirefox 3.6では動作しなくてちょっと悩んだんだけど、Firefox 3.6ではそもそも絶対に再起動が必要だから「変化を可逆的にする」事にこだわらなくてもいいので、そこは横着してダーティなやり方を使ってる。

なんとなく既出のような気もしたけど、「back owner」とかその辺の単語で検索してもそういう物を見つけられなかったので、じゃあ作るか……と思って作ってみた。既出だったら恥ずかしい。

ちなみに、似たような目的のアドオンでTab Historyという物もある。こちらは「新しいタブを開く時に、元のタブの『戻る』『進む』の履歴を引き継ぐようにする」というアプローチを取っている。僕もTab Historyを使ってたんだけど、せっかく作ったので、しばらくはBack to Owner Tabを使って様子を見てみようと思ってる。

新しいタブとかウィンドウとかで「戻る」を押しても戻れねえよムキーッとなる問題を解消するアドオン「親のタブに戻る(Back to Owner Tab)」をリリースしたよ - Jan 01, 1970

Back to Owner Tabというアドオンを作ってみた。

例えば初心者ユーザにはこういう事がありがちだろう。

  • ブラウザのウィンドウを常に最大化して使っている。
  • タブとかウィンドウとかよく分かってない。「戻る」ボタンを押せば1つ前のページに戻れる、という事は(教わったので)知っている。
  • リンクをクリックした結果新しいページが表示されたとして、それがただのページ遷移なのか、新しいタブで開かれたのか、新しいウィンドウで開かれたのか、違いがよく分かってない。
  • 新しいウィンドウで開かれたページを見終わって「元のページに戻ろう」と思って「戻る」ボタンをクリックするが、ボタンをクリックしても何も起こらない。

こういう場面で、「戻る」をクリックしたらとにかく元のタブなりウィンドウなりに戻るようにするのが、このアドオンだ。

だいたい、ウィンドウを最大化してたりタブを表示しないようにしてたりすると、「戻る」で戻れるのかそうでないのかすぐには分からないから、初心者でなくてもこういう物には意味があると思う。

Firefox 3.5以降では browser.tabs.selectOwnerOnClose が true で且つそのタブが「新しいフォアグラウンドのタブ」として開かれた時にだけ「このタブの親はこのタブですよ」という情報が保持される。また、JavaScriptではwindow.openerでオープン元のウィンドウを辿ることができる。このアドオンは、これらの情報を手がかりにして「親のタブ」を検索するようになってる(ツリー型タブがあるならツリーの構造から親のタブを検出する)。

確かタブブラウザ拡張にもこういう機能を含めてた気がするんだけど、それらを単機能の拡張機能として再実装した時に取りこぼしてた。その後、ツリー型タブにこの機能を含めてくれという要望が何回か来てたんだけど、今だったら browser.tabs.selectOwnerOnClose があるから別にツリー型タブに依存した機能にしなくてもいいよなーと思ったので、こうして今回新たに1つのアドオンとして作ってみたというわけ。

Add-on SDKは使ってないけどBootstrapped Extensionsの形にしてあるので、Minefieldでは再起動無しでインストールできる。昨年の発表では「Bootstrapped Extensionsでは『戻る』ボタンの挙動をオーバーライドするみたいな事はできない」と言ったけど、やってみたらできてしまった。あと、そのために使った方法がFirefox 3.6では動作しなくてちょっと悩んだんだけど、Firefox 3.6ではそもそも絶対に再起動が必要だから「変化を可逆的にする」事にこだわらなくてもいいので、そこは横着してダーティなやり方を使ってる。

なんとなく既出のような気もしたけど、「back owner」とかその辺の単語で検索してもそういう物を見つけられなかったので、じゃあ作るか……と思って作ってみた。既出だったら恥ずかしい。

ちなみに、似たような目的のアドオンでTab Historyという物もある。こちらは「新しいタブを開く時に、元のタブの『戻る』『進む』の履歴を引き継ぐようにする」というアプローチを取っている。僕もTab Historyを使ってたんだけど、せっかく作ったので、しばらくはBack to Owner Tabを使って様子を見てみようと思ってる。

新しいタブとかウィンドウとかで「戻る」を押しても戻れねえよムキーッとなる問題を解消するアドオン「親のタブに戻る(Back to Owner Tab)」をリリースしたよ - Jan 01, 1970

Back to Owner Tabというアドオンを作ってみた。

例えば初心者ユーザにはこういう事がありがちだろう。

  • ブラウザのウィンドウを常に最大化して使っている。
  • タブとかウィンドウとかよく分かってない。「戻る」ボタンを押せば1つ前のページに戻れる、という事は(教わったので)知っている。
  • リンクをクリックした結果新しいページが表示されたとして、それがただのページ遷移なのか、新しいタブで開かれたのか、新しいウィンドウで開かれたのか、違いがよく分かってない。
  • 新しいウィンドウで開かれたページを見終わって「元のページに戻ろう」と思って「戻る」ボタンをクリックするが、ボタンをクリックしても何も起こらない。

こういう場面で、「戻る」をクリックしたらとにかく元のタブなりウィンドウなりに戻るようにするのが、このアドオンだ。

だいたい、ウィンドウを最大化してたりタブを表示しないようにしてたりすると、「戻る」で戻れるのかそうでないのかすぐには分からないから、初心者でなくてもこういう物には意味があると思う。

Firefox 3.5以降では browser.tabs.selectOwnerOnClose が true で且つそのタブが「新しいフォアグラウンドのタブ」として開かれた時にだけ「このタブの親はこのタブですよ」という情報が保持される。また、JavaScriptではwindow.openerでオープン元のウィンドウを辿ることができる。このアドオンは、これらの情報を手がかりにして「親のタブ」を検索するようになってる(ツリー型タブがあるならツリーの構造から親のタブを検出する)。

確かタブブラウザ拡張にもこういう機能を含めてた気がするんだけど、それらを単機能の拡張機能として再実装した時に取りこぼしてた。その後、ツリー型タブにこの機能を含めてくれという要望が何回か来てたんだけど、今だったら browser.tabs.selectOwnerOnClose があるから別にツリー型タブに依存した機能にしなくてもいいよなーと思ったので、こうして今回新たに1つのアドオンとして作ってみたというわけ。

Add-on SDKは使ってないけどBootstrapped Extensionsの形にしてあるので、Minefieldでは再起動無しでインストールできる。昨年の発表では「Bootstrapped Extensionsでは『戻る』ボタンの挙動をオーバーライドするみたいな事はできない」と言ったけど、やってみたらできてしまった。あと、そのために使った方法がFirefox 3.6では動作しなくてちょっと悩んだんだけど、Firefox 3.6ではそもそも絶対に再起動が必要だから「変化を可逆的にする」事にこだわらなくてもいいので、そこは横着してダーティなやり方を使ってる。

なんとなく既出のような気もしたけど、「back owner」とかその辺の単語で検索してもそういう物を見つけられなかったので、じゃあ作るか……と思って作ってみた。既出だったら恥ずかしい。

ちなみに、似たような目的のアドオンでTab Historyという物もある。こちらは「新しいタブを開く時に、元のタブの『戻る』『進む』の履歴を引き継ぐようにする」というアプローチを取っている。僕もTab Historyを使ってたんだけど、せっかく作ったので、しばらくはBack to Owner Tabを使って様子を見てみようと思ってる。

新しいタブとかウィンドウとかで「戻る」を押しても戻れねえよムキーッとなる問題を解消するアドオン「親のタブに戻る(Back to Owner Tab)」をリリースしたよ - Jan 01, 1970

Back to Owner Tabというアドオンを作ってみた。

例えば初心者ユーザにはこういう事がありがちだろう。

  • ブラウザのウィンドウを常に最大化して使っている。
  • タブとかウィンドウとかよく分かってない。「戻る」ボタンを押せば1つ前のページに戻れる、という事は(教わったので)知っている。
  • リンクをクリックした結果新しいページが表示されたとして、それがただのページ遷移なのか、新しいタブで開かれたのか、新しいウィンドウで開かれたのか、違いがよく分かってない。
  • 新しいウィンドウで開かれたページを見終わって「元のページに戻ろう」と思って「戻る」ボタンをクリックするが、ボタンをクリックしても何も起こらない。

こういう場面で、「戻る」をクリックしたらとにかく元のタブなりウィンドウなりに戻るようにするのが、このアドオンだ。

だいたい、ウィンドウを最大化してたりタブを表示しないようにしてたりすると、「戻る」で戻れるのかそうでないのかすぐには分からないから、初心者でなくてもこういう物には意味があると思う。

Firefox 3.5以降では browser.tabs.selectOwnerOnClose が true で且つそのタブが「新しいフォアグラウンドのタブ」として開かれた時にだけ「このタブの親はこのタブですよ」という情報が保持される。また、JavaScriptではwindow.openerでオープン元のウィンドウを辿ることができる。このアドオンは、これらの情報を手がかりにして「親のタブ」を検索するようになってる(ツリー型タブがあるならツリーの構造から親のタブを検出する)。

確かタブブラウザ拡張にもこういう機能を含めてた気がするんだけど、それらを単機能の拡張機能として再実装した時に取りこぼしてた。その後、ツリー型タブにこの機能を含めてくれという要望が何回か来てたんだけど、今だったら browser.tabs.selectOwnerOnClose があるから別にツリー型タブに依存した機能にしなくてもいいよなーと思ったので、こうして今回新たに1つのアドオンとして作ってみたというわけ。

Add-on SDKは使ってないけどBootstrapped Extensionsの形にしてあるので、Minefieldでは再起動無しでインストールできる。昨年の発表では「Bootstrapped Extensionsでは『戻る』ボタンの挙動をオーバーライドするみたいな事はできない」と言ったけど、やってみたらできてしまった。あと、そのために使った方法がFirefox 3.6では動作しなくてちょっと悩んだんだけど、Firefox 3.6ではそもそも絶対に再起動が必要だから「変化を可逆的にする」事にこだわらなくてもいいので、そこは横着してダーティなやり方を使ってる。

なんとなく既出のような気もしたけど、「back owner」とかその辺の単語で検索してもそういう物を見つけられなかったので、じゃあ作るか……と思って作ってみた。既出だったら恥ずかしい。

ちなみに、似たような目的のアドオンでTab Historyという物もある。こちらは「新しいタブを開く時に、元のタブの『戻る』『進む』の履歴を引き継ぐようにする」というアプローチを取っている。僕もTab Historyを使ってたんだけど、せっかく作ったので、しばらくはBack to Owner Tabを使って様子を見てみようと思ってる。

新しいタブとかウィンドウとかで「戻る」を押しても戻れねえよムキーッとなる問題を解消するアドオン「親のタブに戻る(Back to Owner Tab)」をリリースしたよ - Jan 01, 1970

Back to Owner Tabというアドオンを作ってみた。

例えば初心者ユーザにはこういう事がありがちだろう。

  • ブラウザのウィンドウを常に最大化して使っている。
  • タブとかウィンドウとかよく分かってない。「戻る」ボタンを押せば1つ前のページに戻れる、という事は(教わったので)知っている。
  • リンクをクリックした結果新しいページが表示されたとして、それがただのページ遷移なのか、新しいタブで開かれたのか、新しいウィンドウで開かれたのか、違いがよく分かってない。
  • 新しいウィンドウで開かれたページを見終わって「元のページに戻ろう」と思って「戻る」ボタンをクリックするが、ボタンをクリックしても何も起こらない。

こういう場面で、「戻る」をクリックしたらとにかく元のタブなりウィンドウなりに戻るようにするのが、このアドオンだ。

だいたい、ウィンドウを最大化してたりタブを表示しないようにしてたりすると、「戻る」で戻れるのかそうでないのかすぐには分からないから、初心者でなくてもこういう物には意味があると思う。

Firefox 3.5以降では browser.tabs.selectOwnerOnClose が true で且つそのタブが「新しいフォアグラウンドのタブ」として開かれた時にだけ「このタブの親はこのタブですよ」という情報が保持される。また、JavaScriptではwindow.openerでオープン元のウィンドウを辿ることができる。このアドオンは、これらの情報を手がかりにして「親のタブ」を検索するようになってる(ツリー型タブがあるならツリーの構造から親のタブを検出する)。

確かタブブラウザ拡張にもこういう機能を含めてた気がするんだけど、それらを単機能の拡張機能として再実装した時に取りこぼしてた。その後、ツリー型タブにこの機能を含めてくれという要望が何回か来てたんだけど、今だったら browser.tabs.selectOwnerOnClose があるから別にツリー型タブに依存した機能にしなくてもいいよなーと思ったので、こうして今回新たに1つのアドオンとして作ってみたというわけ。

Add-on SDKは使ってないけどBootstrapped Extensionsの形にしてあるので、Minefieldでは再起動無しでインストールできる。昨年の発表では「Bootstrapped Extensionsでは『戻る』ボタンの挙動をオーバーライドするみたいな事はできない」と言ったけど、やってみたらできてしまった。あと、そのために使った方法がFirefox 3.6では動作しなくてちょっと悩んだんだけど、Firefox 3.6ではそもそも絶対に再起動が必要だから「変化を可逆的にする」事にこだわらなくてもいいので、そこは横着してダーティなやり方を使ってる。

なんとなく既出のような気もしたけど、「back owner」とかその辺の単語で検索してもそういう物を見つけられなかったので、じゃあ作るか……と思って作ってみた。既出だったら恥ずかしい。

ちなみに、似たような目的のアドオンでTab Historyという物もある。こちらは「新しいタブを開く時に、元のタブの『戻る』『進む』の履歴を引き継ぐようにする」というアプローチを取っている。僕もTab Historyを使ってたんだけど、せっかく作ったので、しばらくはBack to Owner Tabを使って様子を見てみようと思ってる。

新しいタブとかウィンドウとかで「戻る」を押しても戻れねえよムキーッとなる問題を解消するアドオン「親のタブに戻る(Back to Owner Tab)」をリリースしたよ - Jan 01, 1970

Back to Owner Tabというアドオンを作ってみた。

例えば初心者ユーザにはこういう事がありがちだろう。

  • ブラウザのウィンドウを常に最大化して使っている。
  • タブとかウィンドウとかよく分かってない。「戻る」ボタンを押せば1つ前のページに戻れる、という事は(教わったので)知っている。
  • リンクをクリックした結果新しいページが表示されたとして、それがただのページ遷移なのか、新しいタブで開かれたのか、新しいウィンドウで開かれたのか、違いがよく分かってない。
  • 新しいウィンドウで開かれたページを見終わって「元のページに戻ろう」と思って「戻る」ボタンをクリックするが、ボタンをクリックしても何も起こらない。

こういう場面で、「戻る」をクリックしたらとにかく元のタブなりウィンドウなりに戻るようにするのが、このアドオンだ。

だいたい、ウィンドウを最大化してたりタブを表示しないようにしてたりすると、「戻る」で戻れるのかそうでないのかすぐには分からないから、初心者でなくてもこういう物には意味があると思う。

Firefox 3.5以降では browser.tabs.selectOwnerOnClose が true で且つそのタブが「新しいフォアグラウンドのタブ」として開かれた時にだけ「このタブの親はこのタブですよ」という情報が保持される。また、JavaScriptではwindow.openerでオープン元のウィンドウを辿ることができる。このアドオンは、これらの情報を手がかりにして「親のタブ」を検索するようになってる(ツリー型タブがあるならツリーの構造から親のタブを検出する)。

確かタブブラウザ拡張にもこういう機能を含めてた気がするんだけど、それらを単機能の拡張機能として再実装した時に取りこぼしてた。その後、ツリー型タブにこの機能を含めてくれという要望が何回か来てたんだけど、今だったら browser.tabs.selectOwnerOnClose があるから別にツリー型タブに依存した機能にしなくてもいいよなーと思ったので、こうして今回新たに1つのアドオンとして作ってみたというわけ。

Add-on SDKは使ってないけどBootstrapped Extensionsの形にしてあるので、Minefieldでは再起動無しでインストールできる。昨年の発表では「Bootstrapped Extensionsでは『戻る』ボタンの挙動をオーバーライドするみたいな事はできない」と言ったけど、やってみたらできてしまった。あと、そのために使った方法がFirefox 3.6では動作しなくてちょっと悩んだんだけど、Firefox 3.6ではそもそも絶対に再起動が必要だから「変化を可逆的にする」事にこだわらなくてもいいので、そこは横着してダーティなやり方を使ってる。

なんとなく既出のような気もしたけど、「back owner」とかその辺の単語で検索してもそういう物を見つけられなかったので、じゃあ作るか……と思って作ってみた。既出だったら恥ずかしい。

ちなみに、似たような目的のアドオンでTab Historyという物もある。こちらは「新しいタブを開く時に、元のタブの『戻る』『進む』の履歴を引き継ぐようにする」というアプローチを取っている。僕もTab Historyを使ってたんだけど、せっかく作ったので、しばらくはBack to Owner Tabを使って様子を見てみようと思ってる。

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

Powered by blosxom 2.0 + starter kit
Home

カテゴリ一覧

過去の記事

1999.2~2005.8

最近のコメント

最近のつぶやき