2016-04-28 14 views
8

Ich versuche, meine allererste Firefox-Add-on zu implementieren, so dass ich ein Anfänger bin.Wie man eine einfache html-Seite mit einer Schaltfläche mit einem Add-on-Skript kommuniziert mit port.emit

Ich habe über [page-mod] [1] Dokumentation auf Firefox-Webseite gelesen. Ich verstehe immer noch nicht, wie es geht.

Grundsätzlich in einer einfachen HTML-Seite, die ich auf einen Knopf habe, was ich will, ist folgende:

Wenn ich auf die Schaltfläche klicken, die Taste ruft die JavaScript-Funktion runBash() (innerhalb der HTML-Seite erklärt) und kann diese Funktion kommunizieren mit index.js (Add-On-Skript). Es scheint einfach, aber es macht mich verrückt.

[AKTUALISIERT CODE]

index.js/main.js Add-on-Code:

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"); 
    }   
    } 

inhalt 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

Bitte fügen Sie keine Fehler als Screenshots. Kopieren Sie den Text und fügen Sie ihn entweder in einen Angebotsblock ein. Wenn es in einem Angebotsblock nicht gut formatiert wird, verwenden Sie einen Codeblock für den Text. Wenn Fehler als Screenshots enthalten sind, ist die Frage * viel * weniger hilfreich. Es gibt keine Möglichkeit, den Fehlertext zu kopieren oder eine Suche zu finden. – Makyen

Antwort

4

Sie mischen also Ihre Haupt-JS-Datei, die h ist im Grunde Ihre Hintergrundseite für die Erweiterung und das Inhaltsskript, welches das injizierte JS sein wird. In Ihrer package.json Datei geben Sie die 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} 
} 

In main.js, sind Sie erlaubt require und andere SDK-Funktionalität zu nutzen. Für Ihre pageMod, müssen Sie eine separate JS-Datei (die Content-Skript) angeben, die in den HTML-Code des Ziels der pageMod injiziert werden:

EDIT: Sie enthält nicht den Inhalt Skript mit einem <script> Tag in Ihrem HTML wird durch pageMod eingefügt:

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

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

</body> 

auch nur als Alternative, verwende ich worker.on (main.js) und self.postMessage (Content-script.js) für diese. Beispiel:

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'}); 
      } 
     } 
    } 
}); 

Dann in content-script.js:

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

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

Ja, mein Haupt ist: '" main ":" index.js "'. Dann ... Was ist falsch in meinem Code? Ich habe bereits PageMod in 'index.js' hinzugefügt, was soll ich in' content-script.js' einfügen? Ich möchte das nur ausführen: 'function runBash() { self.port.emit (" bash "); } 'wenn ich auf die Schaltfläche klicke ... einfach so, aber ich kann nicht sehen, wie ... – Gera

+0

@Gera Sie müssen, was Sie in der Skript-Tag auf Ihrer HTML-Site zu einem" privilegierten "Inhaltsskript bewegen (zum Beispiel content-script.js), da normale Seitenskripte nicht auf die self.port-API zugreifen können. Sie müssen den Listener auch innerhalb des Inhaltsskripts anhängen, da die Seite das Inhaltsskript nicht sehen kann (und daher nicht die Definition der runBash-Funktion erhält). – humanoid

+0

@humanoid Aber wie kann ich das tun? Kannst du mir mit meinem Code helfen? Ich suchte im Internet und ich kann keine Beispiele finden, ich bin ein wenig verloren mit Firefox Dokumentation. – Gera