正确使用port.emit& main.js和附加到选项卡的脚本之间的port.on

时间:2015-02-06 02:55:33

标签: javascript firefox tabs firefox-addon firefox-addon-sdk

我正在尝试在此扩展中创建一个函数,该函数将打开带有给定URL的选项卡,并在该选项卡上运行具有给定文件名的脚本。该函数主要起作用,除了我无法在主脚本和我在新选项卡上运行的脚本之间进行通信(我使用了.attach)。我知道通信无法正常工作,因为尚未在控制台中打印“Contact successful,over”,这应该通过当前已注释掉的.port函数之一触发。

我几个小时以来一直在浏览Mozilla教程。我很确定我搞砸了一些简单的东西,但是我在教程中找不到一个使用制表符,.port函数和外部脚本的好例子。

Addon的作品: (从Main开始)

  1. 向打开面板(DeltaLogPanel
  2. 的工具栏添加按钮
  3. 此面板有一个按钮,可触发一些用户输入处理(get-text.js)和我们感兴趣的功能(Main.js> TryFA)
  4. 此功能应该打开一个带有给定网址的新标签
  5. 加载此标签后,该功能还应该在此标签上运行存储的脚本(FAmeddle
  6. 该功能需要促进(或至少触发)选项卡脚本与主脚本之间的通信。这包括传递变量
  7. 这些脚本是我的插件的严重缩减版本,但插件工作并保留了第五步的主要问题。

    Main.js

    var data = require("sdk/self").data;
    var journal_entry = require("sdk/panel").Panel({
        contentURL: data.url("DeltaLogPanel.html"),
        contentScriptFile: data.url("get-text.js")
    });
    require("sdk/ui/button/action").ActionButton({
        id: "show-panel",
        label: "Show Panel",
        icon: {
            "16": "./icon-16.png",
            "32": "./icon-32.png",
            "64": "./icon-64.png"
        },
        onClick: handleClick
    });
    function handleClick(state) {
        journal_entry.show();
    }
    journal_entry.on("show", function() {
        journal_entry.port.emit("show");
    });
    
    function ShoutOut(x) {
        console.log(x);
    }
    
    //this should open up a new tab and run a script on it
    function TryFA(URL, SCRIPT) {
    
        var tabs = require("sdk/tabs");
        tabs.open({
            url: URL,
            onReady: function onReady(tab) {
                console.log("the open triggered");
                tab.attach({
                    contentScriptFile: data.url(SCRIPT)
                });
                /* tab.port.on("WeReadYouLoudAndClear",ShoutOut(signal)); */
                //self.port tabs.port and tab.port don't work here
            }
        });
    }
    /* self.port.on("WeReadYouLoudAndClear",ShoutOut(signal)); */
    //tabs.port tab.port and self.port really screw things up here
    
    //This is what the panel button triggered
    journal_entry.port.on("cargo-shipping", function (cargo) {
        journal_entry.hide();
        TryFA("http://www.reddit.com/","FAmeddle.js");
    });
    

    DeltaLogPanel.html

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml">
        <head>
            <style>
                #MainPanel 
                {
                    width: 180px;
                    height:180px;
                    background-color: #ACA1A1;
                }
            </style>
        </head>
        <body id="MainPanel">
            <div id="simpleOptions">
                <textarea id="titleBox" placeholder="Title" rows="1"></textarea>
                <button type="button" id="publishButton">Publish</button>
            </div>
        </body>
    </html>
    

    获取-text.js

    //This script was user for processing and passing along user input. It worked perfectly,
    //so there's not much I need to show you here
    var titleArea = document.getElementById("titleBox");
    var finalButton = document.getElementById("publishButton");
    
    //this defines the cargo on the button press then ships it.
    finalButton.addEventListener('click', function() {
        // Remove the newline.
        var cargo = {
            //This is the user input passed from the panel going to main
            title: ""
        };
        cargo.title = titleArea.value.replace(/[\n\r]/g, '');
        self.port.emit("cargo-shipping", cargo);
        //next we reset everything Note, this doesn't erase local cargo, just the text on the panel
    }, false);
    
    self.port.on("show", function onShow() {
      titleArea.focus();
    });
    

    FAmeddle.js

    function myFunction() {
        var x = document.getElementById("sr-header-area");
        x.style.backgroundColor = "red";
        var signal = "Contact successful, over";
        console.log("the function ran at least");
        self.port.emit("WeReadYouLoudAndClear", signal);
    }
    console.log("Shout out from the extra script!");
    myFunction();
    

    这些是我的问题:

    1. 有没有更好的方法在这样的新打开的标签上运行脚本?
    2. 如何让.port.o n在此工作? (如果有更好的方法在main.js和新页面脚本之间进行通信,请相反解释)
    3. [可选查询]我将多次运行此整体功能。因此,将逐个加载至少六个不同的新选项卡脚本。如何防止这种情况导致性能问题?
    4. 编辑:解决方案 在主要 而不是:

      function TryFA(URL, SCRIPT) {
          var tabs = require("sdk/tabs");
          tabs.open({
              url: URL,
              onReady: function onReady(tab) {
                  console.log("the open triggered");
                  tab.attach({
                      contentScriptFile: data.url(SCRIPT)
                  });
                  tab.port.on("WeReadYouLoudAndClear",ShoutOut(signal));
                  //This ShoutOut function doesn't work for a completely separate reason
              }
          });
      }
      

      使用它:

      function TryFA(URL, SCRIPT) {
          var tabs = require("sdk/tabs");
          tabs.open({
              url: URL,
              onReady: function onReady(tab) {
                  console.log("the open triggered");
                  worker = tab.attach({
                      contentScriptFile: data.url(SCRIPT)
                      });
              worker.port.on("WeReadYouLoudAndClear",function(signal) {
              console.log(signal);
              worker.port.emit("Connection stable", Backback);
              });
              }
          });
      }
      

      编辑2:Backback是从另一个插件代码发送的消息变量。这并不重要。

1 个答案:

答案 0 :(得分:0)

   tab.attach({
       contentScriptFile: data.url(SCRIPT)
   });
   /* tab.port.on("WeReadYouLoudAndClear",ShoutOut(signal)); */
   //self.port tabs.port and tab.port don't work here

tab.attach() returns a worker,后者又有port。正如您在评论中所述,标签本身没有端口。

或者attach也接受回调为onMessage选项。

MDN对于worker和addon-main端口使用也有code examples