X-0002 現在のフレームを参照する

いくつかの方法がありますので、順に説明しましょう。

window._content あるいは getBrowser().contentDocument.defaultView

この両者では、現在表示されている内容領域の window オブジェクトを得ることができます。しかし、フレームを使用したページの場合、トップレベルのフレーム( window.top )しか参照できません。

document.popupNode.ownerDocument.defaultView

document.popupNode.ownerDocument.defaultView は「最後にポップアップメニューを開いた要素が含まれる document オブジェクトが所属している window オブジェクト」で、コンテキストメニューの中で参照すれば、メニューを開いたフレームを確実に参照できます。

ただし、 document.popupNode はメニューを閉じた後も保持されるという点には注意が必要です。 onload 等でページ読み込み時に自動で処理を行う場合、別のページを読み込んだ後に document.popupNode.ownerDocument を参照するとエラーになってしまうのです。また、起動直後に参照してもエラーになります。回避策としては、コンテキストメニューが開かれたときに生成される gContextMenu オブジェクトのあるなしを見て、これを参照するか window._content を使うかを変えるという方法が考えられます。

この方法の問題点は、キーボード操作からでは通常、アクティブなフレームが参照できないということです。キーボードショートカットから機能を呼び出せるようにする場合などは、フレームを使ったページでは機能が使えないということになりがちです。

document.commandDispatcher.focusedWindow

document.commandDispatcher.focusedWindow とすると、最後にコマンドが送られたフレームを参照でき、これを使えば前2者の問題を一気に解決することができます( Moz 自身の検索機能などではこれが使われています)。(ただし、起動直後でコマンドが一度も発行されていない場合には、 focusedWindow は null になります)

実際に使う場合、以下のようにすると良いでしょう。

function getWindow() {
    var focusedWindow = document.commandDispatcher.focusedWindow;
    if (!focusedWindow || focusedWindow == window)
        return window._content;
    else
        return focusedWindow;
}