はじめに
この記事は後期実験「大規模ソフトウェアを手探る」のレポート兼ねた記事で、ここでは選択したタブだけを残し他のタブを削除する機能をつけた際の過程をまとめています。
実装
具体的にどのような実装にしたかというとCtrlとShiftを押したままタブバーをクリックしてタブをいくつか選択し、そのときのタブのインデックスを記憶しておきます。選択したらCtrl+Shift+Fで選択したタブを残して残りを削除します。
タブ選択
このページでも書いたようにbrowser.js内に変更を加えていきます。まず選択したタブのインデックスを記憶しておくために次のものを追加しました。
var tabidx = [];
document.onmousedown = function(event) {
if(event.ctrlKey && event.shiftKey) {
var index = gBrowser.tabContainer.selectedIndex;
for(var i = 0; i < tabidx.length; i++) {
if(index == tabidx[i]) {
tabidx.splice(i, 1);
return;
}
}
tabidx.push(index);
}
}
tabidxという名前をつけた配列にインデックスを追加していきます。Firefoxで定義されている関数を使ったのは4行目の
var index = gBrowser.tabContainer.selectedIndex;
だけで、これは現在選択しているタブのインデックスを取得しています。 for文の部分はすでに選択されているタブをもう一度選択したときにそのタブの選択を解除するように書いています。選択したタブのインデックスがtabidxにあるか検索し、あった場合はtabidxからその要素を消しています。
タブ削除
次に選択したタブを削除するために以下のものを追加しました。
document.onkeydown = function(event) {
if(event.ctrlKey && event.shiftKey && event.keyCode == 70) {
var numtabs = gBrowser.browsers.length;
for(var i = numtabs-1; i >= 0; i--) {
var s = true;
for(var j = 0; j < tabidx.length; j++) {
if(i == tabidx[j]) {
s = false;
break;
}
}
if(s == true) {
var browser = gBrowser.getBrowserAtIndex(i);
var tab = gBrowser._getTabForBrowser(browser);
gBrowser.removeTab(tab, false);
}
}
}
tabidx = [];
}
これで何をしているか説明すると、gBrowser.browsers.lengthで現在開いているタブの数を取得できます。その後大きい方のインデックスからtabidxに含まれているかを確認し、含まれていない場合は削除しています。ページの削除はgBrowser.removeTab関数を使用しました。この関数には引数としてタブオブジェクトを渡す必要があるのでgetBrowserAtIndexメソッドとgetTabForBrowserメソッドを使用して指定したインデックスのタブオブジェクトを取得しています。getBrowserAtIndexは指定したインデックスのブラウザオブジェクトを返すものでgetTabForBrowserはブラウザオブジェクトを受け取ってそのタブオブジェクトを返すものです。削除した後はtabidexを空にします。今回は選択した複数のタブを残して削除するだけでしたが、少し変更するだけで選択した複数のタブを一度にブックマークしたりピン留めしたり出来るようにすることも可能です。
バグ
これで目標の動作は出来るようになりましたがこの実装にはいくつか問題があります。この機能はタブを選択してからすぐに削除することを想定してインデックスを使うような実装にしているのでこのままでは、タブ選択後にタブの削除、追加、並べ替えを行うと選択したタブのインデックスと変更したタブのインデックスが一致せず意図したタブが残せません。本来はタブの変更を監視して変更があるたびにtabidxに反映させるべきなのですが、そこまでは実装できなかったため実際は上のコードに現在のタブの数がtabidxの要素数より少ない時や一つもタブが選択されていない時はalert文で警告を出し削除を行わない例外処理と削除する際にconfirm文を使い自分が消したいページと削除するページが一致しているかを確認するような動作を追加しました。またクリックで選択や選択の解除をした時、タブの色が変わるようにしてどのタブを選択しているかを分かりやすくする機能を追加しようとしたがうまくいかず実装できませんでした。