2012-07-20 58 views
1

我最近开发了一个NPAPI插件(使用FireBreath)和Google Chrome扩展插件。我使用background.html页面嵌入插件,并从多个扩展页面访问它。因此,该插件仍然在后台页面中加载(直到扩展被卸载或浏览器关闭)。使用Firefox Addon SDK在后台嵌入NPAPI插件

我现在正在寻找将此扩展程序移植到Firefox的最简单方法。使用Addon SDK及其API,我可以重现插件代码和HTML用户界面之间的通信。

由于没有像Chrome扩展那样的全局背景DOM,我将如何加载NPAPI插件一次,而不是将其插入应用UI的每个页面?

我已经看到,使用XUL overlay将允许 - 有没有办法使用插件sdk?


编辑:我创建了一个回答这个问题,有一个最小的解决方案,使用页面工这个问题。

回答

3

你会想看看页面工人模块:

https://addons.mozilla.org/en-US/developers/docs/sdk/1.8/packages/addon-kit/page-worker.html

我会给需要说明的是,NPAPI插件,很可能使这件事是对环境的可见性或其他细节的假设运行在那里根本不适用于页面工作者环境。如果您遇到错误,我很乐意听到他们的声音!

+0

页面工人模块允许我打开背景页和使用port.emit,port.on,消息可以在插件和背景之间传递页。然而,这需要记住请求以便在port.on()上提供正确的响应。() – oliverguenther 2012-07-23 19:00:23

+0

好吧,这是SDK中消息传递系统的工作原理。 – canuckistani 2012-07-23 20:49:09

+0

事实证明,使用插件(即访问成员方法),我需要使用'unsafeWindow',否则代理拒绝访问插件。我会相应地更新我的解决方案 – oliverguenther 2012-08-10 08:02:08

0

以下代码为使用页面工作者的问题提供了一个最小工作解决方案,如建议的canuckistani

注意:该解决方案需要addon-sdk的unsafeWindow才能访问插件成员方法。如果有更好的解决方案不依赖于此,请随时向我发送备注/评论。

数据/ background.html

<html> 
    <head> 
     <script type="text/javascript" charset="utf-8"> 
      function pluginLoaded() { 
       // Create an event once plugin is loaded 
       // This allows the contentscript to detect plugin state 
       var evt = document.createEvent("CustomEvent"); 
       evt.initCustomEvent("pluginLoaded", true, false, null); 
       window.dispatchEvent(evt); 
      } 
     </script> 
    </head> 
    <body> 
     <object id="myplugin" type="application/x-myplugin" width="0" height="0"> 
      <param name="onload" value="pluginLoaded" /> 
     </object> 
    </body> 
</html> 

数据/ background.js 变种模块= NULL;

window.addEventListener("pluginLoaded", function(event) { 
    // set the module through unsafeWindow 
    module = unsafeWindow.document.getElementById("myplugin"); 
    module = XPCNativeWrapper.unwrap(module); 
    self.port.emit("pluginLoaded"); 
}); 

// Handle incoming requests to the plugin 
self.port.on("pluginCall", function(msg) { 
    var response; 
    if (module) { 
     // Call NPAPI-plugin member method 
     response = module[msg.method].apply(this, msg.args); 
    } else { 
     response = {error: true, error_msg: "Module not loaded!"}; 
    } 
    self.port.emit("pluginResponse", {data: response}); 
}); 

main.js

// Create background page that loads NPAPI plugin 
var plugin = require("page-worker").Page({ 
    contentURL: data.url("background.html"), 
    contentScriptFile: data.url("background.js"), 
    contentScriptWhen: "ready" 
}); 

// Send request to plugin 
plugin.port.emit("pluginCall", message);