3

Add-on Builderで作成している Add-On に JavaScript 配列を渡す際に問題があります。

通信にはイベントを使用し、配列でイベントを送信していますが、アドオン (コンテンツ スクリプト) は配列ではなくオブジェクトを取得します。

これはイベントです:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> 
<html xml:lang="en" xmlns="http://www.w3.org/1999/xhtml"> 
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<script src="http://code.jquery.com/jquery-latest.min.js" type="text/javascript"></script>
<script type="application/x-javascript">

$(function() {
    $(window).bind('Runner-PageEvent', function(event) {
        console.log('PAGE: Reakcja na Runner-PageEvent na stronie');
    });

    $(window).bind('RunnerResult', function(event) {
        console.log('PAGE: Result is ' + event.originalEvent.detail.Result);

//// PROBLEM!!!
        console.log('PAGE: Should be array: ' + event.originalEvent.detail.array); // firebug shows object

        });

    $(window).bind('Runner-DetectCallback', function(event) {
        console.log('PAGE: Reakcja na Runner-DetectCallback na stronie');
        $('#browser-detection').text('Extension detected').css('background-color', 'green').css('color', 'white');
    });

    var event = new CustomEvent("Runner-Detect", {});
    window.dispatchEvent(event);
    console.log('PAGE: Runner-Detect sent');
});

function CallExtension() {
    var event = new CustomEvent("Runner-PageEvent", { detail : {
            a: "messageA",
            b: "messageB",
            c: "messageC",
            d: "messageD",
            arrayA: ["a", "b", "c", "d"],
            arrayB: [0, "info", "info2", 3]
        }});
    window.dispatchEvent(event);
    console.log('PAGE: CALL EXTENSION clicked');
}

</script> 
</head>
<body>
<div id="browser-detection" style="background-color: red">No extension</div>
<br/>
Run extension: <button onclick="CallExtension()">Run!</button>
</body>
</html>

Firebug はdetail.tab、4 つの項目を持つ配列として 1 つのプロパティを持つオブジェクトとしてイベントを表示します。

コンテンツ スクリプトは object を受け取りますe。ここe.detail.tabで、 はオブジェクトです (ただし、配列である必要があります)。

window.addEventListener(
    'eventname', 
    function(e) { 
        // console.log(e.detail.tab.length); -> produce an error on console (Ctrl+Shift+J)
        // console.log(e.detail.tab[0]); -> as above
        for(var x in e.detail.tab){
            console.log(x);
            console.log(e.detail.tab[x]);
        }            
        self.port.emit('SendToExtension', e.detail);
    }
);


Add-on Builder に問題があるのか​​、何か間違っているのかわかりません。
助けてください!

4

1 に答える 1

3

CustomEvent()サンドボックス ( XPCNativeWrapper ) の内外で情報を送信する方法にバグがあるようです。CustomEventInit.detail特定の状況で値を不適切にシリアル化し、そのような最初のインスタンスの後、detail値をまったく渡すことができません。これは、何らかのメモリ/状態の破損が発生していることを示唆しています。

  1. 以下については、このテスト ページを参照してください: jsbin.com/ajegib/1

  2. この Firefox アドオンCustomEvent data_ across the sandboxをインストールするか、「テスト」モードで実行します。

  3. テスト Web ページと拡張機能のコンテンツ スクリプトの両方に、次のようなコードがあることに注意してください。

    window.addEventListener ("EventWithArrayData", function (zEvent) {
        console.log (
            "Event detail: ", zEvent.detail, Array.isArray (zEvent.detail)
        );
    } );
    
    var zEvent = new CustomEvent ("EventWithArrayData",
        {"detail": [5,6,7] }
    );
    window.dispatchEvent (zEvent)
    
  4. Firebug のコンソールと Firefox エラー コンソール ( ) の両方を開いて、配列値を持つカスタム イベントが送信されCtrlShiftJたときの結果を観察します。detailNormal array dataボタンを押して送信できます。)


何が起こるべきか:

Web ページと拡張機能の両方が、両方のイベントからのデータを配列として見る必要があります。

  1. Firebugコンソールに次のように表示されます。

    **The Normal button was pressed.**
    In web page (Normal) from page: [1, 2, 3]  true
    In web page (Normal) to page: [5, 6, 7]  true
    
  2. FF エラーコンソールに次のように表示されます。

    info: In Content Script (Normal) from page:  1,2,3 true
    info: In Content Script (Normal) to page:  5,6,7 true
    


起こるか:

  1. 最初のイベント:

    1. Firebugコンソールに次のように表示されます。

      **The Normal button was pressed.**
      In web page (Normal) from page: [1, 2, 3]  true
      In web page (Normal) to page: {0: 5, 1: 6, 2: 7}  false
      
    2. FF エラーコンソールに次のように表示されます。

      info: In Content Script (Normal) from page:  [object Object] false
      info: In Content Script (Normal) to page:  5,6,7 true
      
  2. 後続のすべてのイベント:

    1. Firebugコンソールに次のように表示されます。

      **The Normal button was pressed.**
      In web page (Normal) from page: [1, 2, 3]  true
      In web page (Normal) to page: null  false
      
    2. FF エラーコンソールに次のように表示されます。

      info: In Content Script (Normal) from page:  [object Object] false
      info: In Content Script (Normal) to page:  null false
      

観察:

  1. いずれの場合も、Web ページは、独自のイベントによって送信された配列データを正しく認識します。配列が表示されます。
  2. ただし、拡張機能は代わりに配列のようなオブジェクトを認識します。
  3. 拡張機能から送信された配列データは、最初のパスでは拡張機能に正しく表示されますが、その後のすべての試行では null になります。
  4. 拡張機能から送信された配列データは、オブジェクトとしてページに表示されますが、まったく表示されません ( null)!


回避策:

CustomEvent ドキュメントDOM 標準状態の両方で、eventInitDict.detail任意の型を持つことができます。しかし、アドオン サンドボックスを介して送信されるイベントの場合、これは明らかに当てはまりません。これに関する Firefox のバグ
はないようです。おそらく、私たちはそれを開く必要があります。

とにかく、うまくいくと思われる回避策は、送信するデータを JSON でエンコードすることCustomEvent()です。

次のように送信します。

var detailVal   = JSON.stringify ( [1, 2, 3] );

var zEvent = new CustomEvent ("EventWithJSON_Data",
    {"detail": detailVal }
);
window.dispatchEvent (zEvent)

次のように受け取ります。

window.addEventListener ("EventWithJSON_Data", function (zEvent) {
    var datArray    = JSON.parse (zEvent.detail);
    console.log (
        "JSON data: ", datArray, Array.isArray (datArray)
    );
} );


ボタンを押すと、テスト ページ + 拡張機能でこれが機能していることがわかりJSON-encoded array dataます。(上記の破損を解消するために、必ず最初にページを更新してください。)

于 2012-10-11T17:37:59.163 に答える