Firefox sdk - content script cannot access self.port

I am trying to create a firefox addon using their sdk, but I do not know how to make my js scripts shared. The goal is to make a panel with a form in 3 flags, which, when selected, can hide / show certain elements on the active tab.

Here are the scripts: main.js:

exports.main = function() {}; var data = require("sdk/self").data; var panel1 = require("sdk/panel").Panel({ width: 215, height: 160, contentURL: data.url("panelDestroyer.html"), contentScriptFile: [data.url("jquery.js"),data.url("panel.js")] }); require("sdk/widget").Widget({ id: "open-form-btn", label: "Clear", contentURL: data.url("mozico.png"), contentScriptFile: data.url("jquery.js"), panel: panel1 }); var tabs = require("sdk/tabs"); var tabWorkers = {}; tabs.on("ready", function(tab) { attachTabWorker(tab); }); for each (var tab in tabs) { attachTabWorker(tab); } function attachTabWorker(tab) { // Attach and store var tabWorker = tabWorkers[tab.id] = tab.attach({ contentScriptFile: [data.url("clear.js"),data.url("jquery.js")] }); // Clean up tabWorker.on("detach", function() { if (getTabWorker(tab) === tabWorker) { delete tabWorkers[tab.id]; } }); } function getTabWorker(tab) { return tabWorkers[tab.id]; } function getActiveTabWorker() { return getTabWorker(tabs.activeTab); } panel1.port.on("show-tag",function(tag){ getActiveTabWorker().port.emit("show-tag", tag); console.log("worker emited"); }); panel1.port.on("clear-tag",function(tag){ getActiveTabWorker().port.emit("clear-tag", tag); console.log("worker emited"); }) 

;

painel.js:

  $("#imgD").click(function() { if ($(this).is(":checked")) { self.port.emit("clear-tag","img"); console.log("panel emited"); } else { self.port.emit("show-tag","img"); console.log("panel emited"); } }); $("#aD").click(function() { if ($(this).is(":checked")) { self.port.emit("clear-tag","a"); console.log("panel emited"); } else { self.port.emit("show-tag","a"); console.log("panel emited"); } }); $("#iframeD").click(function() { if ($(this).is(":checked")) { self.port.emit("clear-tag","iframe"); console.log("panel emited"); } else { self.port.emit("show-tag","iframe"); console.log("panel emited"); } }); 

clear.js:

  function tagHide (tag, hide) { $(tag).each(function() { if (hide === false) { $(this).css({ "visibility": "visible" }); } else { $(this).css({ "visibility": "hidden" }); } }); } self.port.on('show-tag', function(tag) { tagHide(tag, false); }); self.port.on('clear-tag', function(tag) { tagHide(tag, true); }); 

Why do I keep getting self.port not defined in painel.js?

+4
source share
2 answers

I believe the problem is that you are trying to include content script when loading the add-in.

 let worker = require("sdk/tabs").activeTab.attach({ contentScriptFile: data.url("clear.js") }); 

I think that activeTab might not be ready when your add-on is just loaded, which usually happens when Firefox starts. Perhaps the DOM is not yet fully loaded or the SDK was unable to correctly initialize all the components for the content script.

The SDK documentation indicates that you must wait for the ready event before using the properties and methods associated with the content. I assume that attachment of content scripts also falls into this category, so you probably have to redo something like:

 let worker = null; require("sdk/tabs").activeTab.on("ready", function(tab) { worker = tab.attach({ contentScriptFile: data.url("clear.js") }); }); 

This is still not enough, as the user can switch tabs. When you register the ready listener in the original activeTab , you will not listen to the newly activated tab, and no content scripts will be attached to this tab. You will need:

  • Listen to the ready event of all tabs
  • make sure they all have attached script content;
  • Select the appropriate employee based on the currently active tab.

I quickly whipped what exactly this was supposed to do. You should be able to use getActiveTabWorker() in your panel port events to set the correct working one. It is still not verified, so give it a try!

 const tabs = require("sdk/tabs"); let tabWorkers = {}; tabs.on("ready", function(tab) { attachTabWorker(tab); }); for each (let tab in tabs) { attachTabWorker(tab); } function attachTabWorker(tab) { // Attach and store let tabWorker = tabWorkers[tab.id] = tab.attach({ contentScriptFile: data.url("clear.js") }); // Clean up tabWorker.on("detach", function() { if (getTabWorker(tab) === tabWorker) { delete tabWorkers[tab.id]; } }); } function getTabWorker(tab) { return tabWorkers[tab.id]; } function getActiveTabWorker() { return getTabWorker(tabs.activeTab); } 

EDIT: I have no idea how self.port can be undefined, but I found a few more errors that you need to fix. Perhaps one of them indirectly interferes with self ?

  • main.js listens for hide-tag , while your panel emits clear-tag . Use clear-tag .
  • You give the object to the employee, while your employee expects only a string. Just emit tag instead of {tag:tag} .
  • You do not include jQuery in your working column. Add data.url("jquery.js") to the contentScriptFile in attachTabWorker .
+5
source

I also experienced the same problem and then found this question in SO: self.port is undefined error [on mozilla add-on SDK 1.8]

The problem is in the HTML code, you have to call the script in both main.js and html. Removing it from html and declaring it directly in main.js will resolve this error.

+1
source

Source: https://habr.com/ru/post/1483889/


All Articles