1

ウィジェットである再起動なしのアドオンを構築していCustomizableUIます。

CustomizableUI.createWidget()中に電話するとき、その物件を優先エリアの選択の 1 つにしてstartup()ほしいのですが。defaultArea現在、私は次のようなものでこれを達成しています:

// ordered from most to least preferred
let preferredAreas = [
  'ctraddon_addon-bar',
  'ctraddon_extra-bar',
  CustomizableUI.AREA_BOOKMARKS,
  CustomizableUI.AREA_NAVBAR,
  // null basically translates to 'PanelUI-contents'
  // but this makes it easy to test later on
  null
];

let registeredAreas = CustomizableUI.areas;
let preferredArea;
for( let i = 0, l = preferredAreas.length; i < l; i++ ) {
  preferredArea = preferredAreas[ i ];
  if( registeredAreas.indexOf( preferredArea ) > -1 ) {
    break;
  }
}

if( !preferredArea ) { // i.e. null
  /* on first run: notify user that we were unable to find a preferred area */
}

CustomizableUI.createWidget( {
  id: 'myAddon',
  type: 'custom',
  defaultArea: preferredArea,
  /* etc */
} );

つまり、優先エリアが存在するかどうかを確認しています。startup()インストール直後の では、これはほとんど期待どおりに機能します。これは、基本的にすべての対象領域 (Classic Theme Restorer などの他の拡張機能から) が既に登録されているためです。ただし、アドオンが既にインストールされていて、Firefox が起動したときCustomizableUI.areasは、関心のあるすべての領域がまだ満たされていません (おそらく、関心のある領域を登録する拡張機能よりも先に拡張機能が読み込まれるためです)。

を利用してみましたがmostRecentWindow.addEventListener( 'load', /* etc */ )mostRecentWindowは の戻り値ですがnsIWindowMediator.getMostRecentWindow( 'navigator:browser' )

  1. アプリの起動時mostRecentWindownull
  2. アドオンのインストール時にイベントが発生しなくmostRecentWindowなりましたload

CustomizableUI.createWidget()だから、私の質問は次のとおりです。関連するすべてのコードがロードされるまで呼び出しを待つ簡単で効果的な方法は何ですか?


私がやったことは次のとおりです(これはNoitidartが提案したものでもあります)。これはうまくいくようです:

let createWidget = function() {
    /* all the preferredArea and CustomizableUI.createWidget() stuff from above */
}

let mostRecentBrowserWindow = windowMediator.getMostRecentWindow( 'navigator:browser' );
if( null == mostRecentBrowserWindow ) {
  let windowListenerWidget = {
    onOpenWindow: function( wrappedWindow ) {
      windowMediator.removeListener( windowListenerWidget );
      let domWindow = wrappedWindow.QueryInterface( Ci.nsIInterfaceRequestor )
                                   .getInterface( Ci.nsIDOMWindow );
      domWindow.addEventListener( 'load', function onWindowLoad( event ) {
        this.removeEventListener( 'load', onWindowLoad );
        createWidget();
      } );
    }
  }
  windowMediator.addListener( windowListenerWidget );
}
else {
  createWidget();
}
4

1 に答える 1

1

あなたがしなければならないことは、 のリスナーを追加することですonAreaNodeRegistered。コールバックでウィジェットを作成します。

MDN :: CustomizableUI.jsm - addListener()を参照してください。

onAreaNodeRegistered と onAreaNodeUnregsitered は mdn にないため、定義は次のとおりです: http://mxr.mozilla.org/mozilla-release/source/browser/components/customizableui/src/CustomizableUI.jsm#2704

2704    *   - onAreaNodeRegistered(aArea, aContainer)
2705    *     Fired after an area node is first built when it is registered. This
2706    *     is often when the window has opened, but in the case of add-ons,
2707    *     could fire when the node has just been registered with CustomizableUI
2708    *     after an add-on update or disable/enable sequence.
2709    *   - onAreaNodeUnregistered(aArea, aContainer, aReason)
2710    *     Fired when an area node is explicitly unregistered by an API caller,
2711    *     or by a window closing. The aReason parameter indicates which of
2712    *     these is the case.
2713    */

したがって、実装のためにこれを行います:

まず、目的のエリアが存在するかどうかを確認します。そうでない場合は、リスナーを追加します。そして、リスナーでウィジェットを作成します。

var targetAreaId = 'blah'; //the id of area you want test for, meaning the area you want to add your widget too, targetAreaId can be CustomizableUI.AREA_NAVBAR, basically its the id (first arg) argument of CustomizableUI.registerArea('blahIdHere'..

function createMyWidget() {
  CustomizableUI.addWidget({
     id: "edit-controls",
    type: "custom",
    defaultArea: targetAreaId,
    onBuild: function(aDocument) {}
    //........ blah blah balh
  })
}


if (CustomizableUI.areas.indexOf(targetAreaId) > -1) { // customizableUI.areas is an array for example for me it is:`Array [ "PanelUI-contents", "nav-bar", "toolbar-menubar", "TabsToolbar", "PersonalToolbar", "addon-bar", "thePuzzlePiece-addon-bar" ]`
  createMyWidget();
} else {    
    var myCustUiListener = {
      'onAreaNodeRegistered': function(aArea, aContainer) {
        //create your widget here
        if (aArea.id == targetAreaId) { //im not sure of the properties on aArea do a console.log('aArea properties:', aArea) to see what all properties are there
         createMyWidget();
        }
      }
    };
    CustomizableUI.addListener(myCustUiListener);
}
于 2014-09-08T21:11:04.017 に答える