2016-04-28 22 views
8

我试图实现我的第一个Firefox附加组件,所以我完全是初学者。如何使用port.emit通信包含按钮的简单html页面和附加脚本

我一直在阅读关于Firefox网页上的[page-mod] [1]文档。我仍然不明白如何去做。

基本上在一个基本的HTML页面我有一个按钮,我想是这样的:

如果我按一下按钮,该按钮调用JavaScript函数runBash()(HTML页面内声明的)和该功能可与index.js(附加脚本)进行通信。看起来很简单,但是这让我发疯。

[更新的代码]

index.js/main.js附加代码:

var { ToggleButton } = require('sdk/ui/button/toggle'); 
    var panels = require("sdk/panel"); 
    var self = require("sdk/self"); 
    var data = require("sdk/self").data; 
    var pageMod = require("sdk/page-mod"); 

    pageMod.PageMod({ 
    include: data.url("./bash.html"), 
    contentScriptFile: data.url("./content-script.js"), 
    contentScriptWhen: "ready", // script will fire when the event DOMContentLoaded is fired, so you don't have to listen for this 
    attachTo: ["existing", "top"], 
    onAttach: function(worker) { 
     worker.port.on("bash", function() { 
     //var bash = child_process.spawn('/bin/sh', ['/root/tfg/data/test.sh']); 
     alert("IT WORKS!"); 
     }); 
    } 
    }); 


    var button = ToggleButton({ 
    id: "my-button", 
    label: "UPF", 
    icon: { 
     "16": "./favicon-16.ico", 
     "32": "./favicon-32.ico", 
     "64": "./favicon-64.ico" 
    }, 
    onChange: handleChange 
    }); 

    var panel = panels.Panel({ 
    contentURL: self.data.url("./panel.html"), 
    onHide: handleHide 
    }); 

    var lynisAlreadyExecuted = false; 
    function handleChange(state) { 

     if (lynisAlreadyExecuted == false) { 
     var child_process = require("sdk/system/child_process"); 

     var ls = child_process.spawn('/usr/sbin/lynis', ['-c', '-q']); 

     ls.stdout.on('data', function (data) { 
      console.log('stdout: ' + data); 
     }); 

     ls.stderr.on('data', function (data) { 
      console.log('stderr: ' + data); 
     }); 

     ls.on('close', function (code) { 
      console.log('child process exited with code ' + code); 
     }); 
     lynisAlreadyExecuted = true; 
     } 

    if (state.checked) { 
     panel.show({ 
     position: button 
     }); 
    } 
    } 

    function handleHide() { 
    button.state('window', {checked: false}); 
    } 

    function enableButton2() { 
    var information = String(navigator.userAgent); 
    var checkOS = information.includes("Linux",0); 
    var checkBrowser = information.includes("Firefox",0); 
    if(checkOS && checkBrowser){ 
     alert("Your system meets the minimum requirements! :)"); 
     document.getElementById("button2").disabled = false; 
    } 
    else{ 
     alert("Your System is not compatible"); 
    }   
    } 

内容的script.js:

function runBash() { 
    // rest of your code 
    self.port.emit("bash"); 
} 

bash.html:

<!DOCTYPE html> 
<html> 
<head> 
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> 
<link rel="stylesheet" href="../css/layout.css" type="text/css" media="screen"> 
<link rel="stylesheet" href="../css/menu.css" type="text/css" media="screen"> 

</head> 
<body> 
    <script src="content-script.js"></script> 

    <input type="button" value="CallBash" onclick="runBash();"> 

</body> 
</html> 
+0

请不要加错误的屏幕截图。复制文本并将其包含在报价块中。如果在引用块中格式不正确,则使用文本的代码块。将错误包含在屏幕截图中会使问题变得非常有用。无法复制错误文本,也无法搜索查找错误文本。 – Makyen

回答

4

所以你正在混合你的主要JS文件,whic h基本上是你的扩展的后台页面,而内容脚本,这将是注入的JS。在你package.json文件,你指定main

{ 
    "name": "my-addon", 
    "title": "My Addon", 
    "id": "12345678", 
    "description": "Does cool things.", 
    "author": "me", 
    "version": "1.0", 
    "main": "main.js", <--- this is your main 
    "permissions": {"private-browsing": true} 
} 

main.js,你被允许使用require,和其他SDK功能。为了您pageMod,你需要指定将被注入到pageMod目标的HTML一个独立的JS文件(内容脚本):

编辑:不要包含内容脚本在<script>标签您HTML,它被插入通过pageMod

<body> 
    <!-- <script src="content-script.js"></script> don't put this here --> 

    <input type="button" value="CallBash" onclick="runBash();"> 

</body> 

另外,只是作为一个替代方案中,我使用worker.on(main.js)和self.postMessage(内容的script.js)这一点。例如:

pageMod.PageMod({ 
    include: data.url('bash.html'), 
    contentScriptFile: data.url("content-script.js"), //<-- this is the content script 
    contentScriptWhen: "ready", 
    attachTo: ["existing", "top"], 
    onAttach: function (worker) { 
     worker.on("message", function(data) { 
      if (data['action'] == 'bash') { 
       worker.postMessage({'action':'did_bash'}); 
      } 
     } 
    } 
}); 

然后在content-script.js

function runBash() { 
    self.postMessage({'action':'bash'}); 
} 

self.on('message', function (reply) { 
    if (reply['action'] == 'did_bash') { 
     console.log('It works!'); 
    } 
} 
+0

是的,我的主要是:''main“:”index.js“'。那么......我的代码有什么问题?我已经在'index.js'中添加了PageMod,我应该把什么放在'content-script.js'上?我只是想执行这个:'function runBash(){ self.port.emit(“bash”); }'当我点击按钮时...那么简单,但我看不到如何...... – Gera

+0

@Gera您必须将HTML网站上脚本标记中的内容移至“特权”内容脚本(例如content-script.js),因为普通的页面脚本不能访问self.port API。您还必须在内容脚本中附加侦听器,因为该页面将无法看到内容脚本(因此无法获得runBash函数的定义)。 – humanoid

+0

@humanoid但我该怎么做?你能帮我用我的代码吗?我在网上搜索,找不到示例,我用firefox sdk文档丢失了一点点。 – Gera

相关问题