javascript - Firefox 扩展将 Javascript 数组作为对象发送

标签 javascript firefox-addon firefox-addon-sdk dom-events content-script

我在将 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有问题还是我哪里做错了?
请帮忙!

最佳答案

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. 打开 both Firebug 的控制台,以及 Firefox 错误控制台(CtrlShift J) 以观察结果,因为发送了带有 detail 数组值的自定义事件。 (您可以按普通数组数据按钮,发送它们。)


应该发生什么:

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

  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)!


解决方法:

两者都是the CustomEvent documentationthe DOM Standard说明 eventInitDict.detail 可以是任何类型。但对于通过附加沙箱发送的事件,情况显然并非如此。
好像没有Firefox bugs为了这。也许我们应该打开一个。

无论如何,似乎可行的解决方法是对我们使用 CustomEvent() 发送的数据进行 JSON 编码。

像这样发送:

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 编码数组数据 按钮在测试页 + 扩展程序上看到这一点。 (一定要先刷新页面以清除上面讨论的损坏。)

关于javascript - Firefox 扩展将 Javascript 数组作为对象发送,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12727733/

相关文章:

javascript - 如果 div 固定则显示完整内容

javascript - 如何以 Angular 等待订阅

javascript - 如何动态安全地设置 XUL key ?

firefox-addon - 如何在 Firefox 插件中以编程方式打开开发者工具的控制台?

firefox-addon - 如何从 Firefox 插件观察 websocket 事件?

javascript - 使用内容脚本定义全局变量

javascript Highcharts JSON 数据到 HTML 表格

javascript - 将函数分配给 JSON 属性

javascript - 在 Firefox 上执行之前创建一个插件来修改 JavaScript 数据

css - 如何在 firefox 插件中创建垂直标签?