3

我在将 JavaScript 数组传递给我在Add-on Builder中编写的插件时遇到问题。

为了进行通信,我使用事件并使用数组发送事件,但附加组件(内容脚本)获取的是对象,而不是数组。

这是事件:

<!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作为具有四个项目的数组。

内容脚本接收一个对象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. 请注意,测试网页和扩展的内容脚本都有如下代码:

    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) 以观察结果,因为发送了带有数组值的自定义事件detail。(您可以按下Normal array data按钮,发送它们。)


应该发生什么:

网页和扩展程序都应该将来自这两个事件的数据视为一个数组。

  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. 在所有情况下,网页都正确地看到了它自己的事件发送的数组数据。它看到一个数组。
  2. 但是,扩展看到的是一个类似数组的对象。
  3. 从扩展程序发送的数组数据在第一次传递时正确显示给扩展程序,但在所有后续尝试中为空。
  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 回答