2016-04-28 35 views
8

Próbuję zaimplementować mój pierwszy dodatek do Firefoksa, więc jestem całkowicie początkującym.Jak przekazać prostą stronę HTML zawierającą przycisk z dodatkowym skryptem przy użyciu portu.emit

Czytałem o dokumentacji [page-mod] [1] na stronie Firefoksa. Nadal nie rozumiem, jak to zrobić.

Zasadniczo w podstawowej strony html Mam przycisk, co chcę jest następująca:

Gdybym kliknij przycisk, przycisk wywołuje funkcję JavaScript runBash() (deklarowane wewnątrz strony html) i funkcja ta może komunikować się z index.js (skryptem dodatkowym). Wydaje się to proste, ale doprowadza mnie to do szału.

[uaktualnionych]

index.js/main.js dodatkowy kod:

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

Content-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

Prosimy nie dodawać błędy jak zrzuty ekranu. Skopiuj tekst i umieść go w bloku wyceny. Jeśli nie formatuje się dobrze w bloku wyceny, użyj bloku kodu dla tekstu. Uwzględnienie błędów w postaci zrzutów ekranu sprawia, że ​​pytanie * dużo * jest mniej przydatne. Nie ma możliwości skopiowania lub znalezienia szukanego tekstu błędu. – Makyen

Odpowiedz

4

Więc mieszasz swój główny plik JS, który h to w zasadzie twoja strona tła dla rozszerzenia oraz skrypt treści, który będzie wstrzykiwanym JS. W pliku package.json podajesz 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} 
} 

w main.js, masz prawo do korzystania require i inne funkcje SDK. Dla Państwa pageMod, trzeba określić oddzielny plik JS (skrypt treści), które zostaną wstrzyknięte do HTML do docelowej pageMod:

EDIT: Nie zawiera skrypt treści z <script> tag w twojej HTML jest włożona przez pageMod:

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

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

</body> 

również tylko jako alternatywa, używam worker.on (main.js) i self.postMessage (content-script.js) do tego. Przykład:

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

Następnie w content-script.js:

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

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

Tak, moim głównym jest: '" main ":" index.js "'. Więc ... co jest nie tak w moim kodzie? Dodałem już stronę PageMod do pliku "index.js", co powinienem napisać na "content-script.js"? Chcę tylko wykonać to: 'function runBash() { self.port.emit (" bash "); } 'gdy klikam przycisk ... to proste, ale nie widzę ... – Gera

+0

@Gera musisz przenieść to, co masz w znaczniku skryptu na stronie HTML, do" uprzywilejowanego "skryptu treści (na przykład content-script.js), ponieważ normalne skrypty strony nie mają dostępu do interfejsu self.port API. Będziesz musiał także dołączyć detektor z poziomu skryptu treści, ponieważ strona nie będzie w stanie zobaczyć skryptu zawartości (a tym samym nie otrzyma definicji funkcji runBash). – humanoid

+0

@humanoid Ale jak mogę to zrobić? Czy możesz mi pomóc z moim kodem? Szukałem w Internecie i nie mogę znaleźć przykładów, jestem trochę zagubiony z dokumentacją sdk firefox. – Gera