X-0020 nsISimpleEnumerator を使う

string.match(regexp)string.split() のようなメソッドは、結果のリストを配列( Array )の形で返します。すべてのアイテムを処理する場合、以下のように書くことになります。

var result = string.split();
for (var i = 0; i < result.length; i++)
  alert(result[i]);

それに対して、 XPCOM のインターフェースのメソッドの多く、例えば nsIWindowMediator の getEnumerator() メソッド(すべてのウィンドウを返す)や、 nsIRDFContainer の GetElements() メソッド(すべての要素を返す)は、 nsISimpleEnumerator という形で結果のリストを返します。これは配列とは違うため、前述のような単純な for ループではすべての要素を取り出せません。

nsISimpleEnumerator からそれぞれの要素を取り出すには、二つのステップを踏みます。まず、 getNext()メソッドで「次の要素」を取り出す。次に、取り出した要素を適切なインターフェースで扱えるようにする。以下は、この操作を自動化して、 nsISimpleEnumerator を配列に変換する関数の例です。

function getArrayFromEnumerator(aEnumerator, aInterface)
{
   var item;
   var array = []; // array = new Array();
   while (aEnumerator.hasMoreElements())
   {
      item = aEnumerator.getNext();
      item = item.QueryInterface(Components.interfaces[aInterface]);
      array.push(item);
   }
   return array;
}

const windowManager = Components.classes['@mozilla.org/appshell/window-mediator;1']
                                .getService(Components.interfaces.nsIWindowMediator);
var winArray = getArrayFromEnumerator(
                  windowManager.getEnumerator('navigator:browser'),
                  'nsIDOMWindowInternal'
               );