2012-03-08 143 views
4

我正在写一个Firefox扩展,在命令行中需要自定义开关,并在components目录设置我cmdline.js内部变量全局变量,我们称之为可变switchDetected这是一个布尔值。现在基于这个变量,我想要在chrome/content目录中的overlay.js文件中执行操作。 我遇到的问题是我似乎无法访问中从chrome/contents/overlay.js中声明的变量switchDetected访问在Firefox扩展

我已经尝试了很多方法来做到这一点,但似乎没有任何工作。所以我只是想知道是否有人知道如何实现。

+0

SOLUTION(我会适当加了这一点让我,6小时) 通常我发现了解决方案张贴问题,10分钟后。解决方案是使用Javascript代码模块。这里是链接 https://developer.mozilla.org/zh/JavaScript_code_modules/使用 我用getter和setters而不是暴露变量我想改变,因为它似乎暴露变量本身并没有工作,但功能,这是很好的。 我希望这可以节省其他人无尽的搜索。 – Lipwig 2012-03-08 13:33:23

+0

那么,使用JavaScript模块是另一种可能 - 但如果您已经有XPCOM组件,您可以直接与它通信。看到我的答案。 – 2012-03-08 13:44:13

回答

4

加载到叠加层中的脚本在浏览器窗口的上下文中运行 - 其全局变量存储为与浏览器对应的window对象的属性。如果打开第二个浏览器窗口,则同一脚本将再次加载并在新浏览器窗口的上下文中运行 - 它将具有不同的全局变量。另一方面,包含XPCOM组件的脚本只加载一次,并且它们具有未绑定到窗口的独立上下文。所以他们的全局变量不能直接从浏览器窗口访问,就像两个浏览器窗口不能直接访问其他全局变量一样。

相反,浏览器窗口应该使用通常的方法与XPCOM组件通信:获取组件实例并调用其方法。如果您不想定义自己的接口,用于(你可能不),你可以use a trick,这样的事情:

CommandLineHandler.prototype = { 
    handle: function(commandLine) {...}, 
    get helpInfo() {...}, 
    isSwitchDetected: function() 
    { 
    return switchDetected; 
    }, 
    get wrappedJSObject() 
    { 
    return this; 
    }, 
    QueryInterface: XPCOMUtils.generateQI(["nsICommandLineHandler"]); 
}; 

wrappedJSObject特性可确保您的组件可以解开 - 所有的方法并且属性将变得可以访问,而不仅仅是在界面中定义的属性。所以,你的覆盖脚本需要做到以下几点:

var cmdLineHandler = Components.classes["@myself.com/my-command-line-handler;1"] 
           .getService() 
           .wrappedJSObject; 
var switchDetected = cmdLineHandler.isSwitchDetected(); 
+0

干杯,很好的解释我会给它一个去 – Lipwig 2012-03-08 15:34:33